I'm looking for bad examples of using inheritance. I'm not very creative so this was the best I could think of:
class Car : public Engine {}
A car has an engine, but it is not an engine.
This would probably work to explain the concept, but I believe there are more illustrative examples?
The "classic" example ;-):
public class Stack extends Vector {
...
}
A Stack is NOT a Vector.
If Stack extends Vector, you are able to insert/delete at every given index, whereas you should only be allowed to add/delete elements by pushing/popping.
Use pretty much any example that uses inheritance without regard to the behavior of the base class.
A classic example is the relationship between Square and Rectangle. Sure, in mathematics, a square is a type of a rectangle. However, in software design, a square doesn't behave like a rectangle:
public class Rectangle
{
public virtual int Width { get; set; }
public virtual int Height { get; set; }
}
public class Square : Rectangle
{
public override int Width
{
get { return base.Width; }
set
{
base.Width = value;
base.Height = value;
}
}
public override int Height
{
get { return base.Height; }
set
{
base.Height= value;
base.Width = value;
}
}
}
If another class, Client, needs a Rectangle but gets a Square, Client will break because it expects its Rectangle to have a Width and Height that don't affect each other.
Inheritance is very useful, but also breaks encapsulation. This means that your subclasses depend on implementation details of the superclass; if the superclass changes, your subclass may break. Here's an example in Java, from Effective Java by Josh Bloch:
public class InstrumentedHashSet<E> extends HashSet<E> {
// number of attempted element insertions
private int addCount = 0;
public int getAddCount() {
return addCount;
}
#Override public boolean addAll<Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
}
}
The problem is that HashSet's addAll() method uses its add() method internally, but doesn't document this. So if you try
InstrumentedHashSet<String> s = new InstrumentedHashSet<String>();
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
you end up with a count of 6 instead of 3. In this particular case that isn't very harmful, but if you were adding a large collection or doing some other operation, it could be.
So, concrete classes are usually not a good idea to inherit from, unless they were designed to have subclasses.
This have been debated for years, and you'll find a lot of materials/talks referencing the problem on google.
public class Square extends Rectangle {
...
}
Perhaps not very surprising though, a square should not inherit from a rectangle.
Related
Liskov Substitution Principle requires that
Preconditions cannot be strengthened in a subtype.
Postconditions cannot be weakened in a subtype.
Invariants of the supertype must be preserved in a subtype.
History constraint (the "history rule"). Objects are regarded as being modifiable only through their methods (encapsulation). Since subtypes may introduce methods that are not present in the supertype, the introduction of these methods may allow state changes in the subtype that are not permissible in the supertype. The history constraint prohibits this.
Can anybody please post an example violating each of these points and another example solving those?
All four items in the question have been thoroughly reviewed in this article.
Preconditions cannot be strengthened in a subtype.
This answer presents "real duck" and "electric duck" example, I suggest you go check it out. I'll use it in this item, for brevity.
It means that subtypes can't get in the way of how the original methods behaved in the base class. In the above mentioned answer's code, both ducks can swim, but the ElectricDuck will only swim if it's turned on. Therefore, any unit of code that requires that a duck (from the interface IDuck) swim now won't work, unless explicitly specified that the duck is ElectricDuck (and then turned on), which needs to be implemented everywhere.
Postconditions cannot be weakened in a subtype.
For this one, we can step back from the duck analogy. Let's take this answer as a base. Assume we have a baseclass that accepts only positive integers. If in a subtype, while extending the method, we remove the condition that the number must be positive, then all units of code that used to take for granted that the number was positive is now under risk of breaking, since now there's no guarantee that the number is positive. Here's a representation of this idea:
public class IndexBaseClass
{
protected int index;
public virtual int Index
{
get
{
//Will return positive integers only
return index < 0 ? 0 : index;
}
set
{
index = value;
}
}
}
public class IndexSubClass : IndexBaseClass
{
public override int Index
{
get
{
//Will pay no mind whether the number is positive or negative
return index;
}
}
}
public class Testing
{
public static int GetIndexOfList(IndexBaseClass indexObject)
{
var list = new List<int>
{
1, 2, 3, 4
};
return list[indexObject.Index];
}
}
If we call GetIndexOfList passing an IndexSubClass object, there's no guarantee that the number will be positive, hence potentially breaking the application. Imagine you're already calling this method from all over your code. You'd have to waste your time checking for positive values in all implementations.
Invariants of the supertype must be preserved in a subtype.
A parent class may have some invariants, that is, some conditions that must remain true for as long as the object exists. No subclass should inherit the class and eliminate this invariant, under the risk of all implementations so far breaking down. In the example below, the parent class throws an Exception if it's negative and then set it, but the subclass just plain ignores it, it just sets the invariant.
The following code was taken from here:
public class ShippingStrategy
{
public ShippingStrategy(decimal flatRate)
{
if (flatRate <= decimal.Zero)
throw new ArgumentOutOfRangeException("flatRate", "Flat rate must be positive
and non-zero");
this.flatRate = flatRate;
}
protected decimal flatRate;
}
public class WorldWideShippingStrategy : ShippingStrategy
{
public WorldWideShippingStrategy(decimal flatRate)
: base(flatRate)
{
//The subclass inherits the parent's constructor, but neglects the invariant (the value must be positive)
}
public decimal FlatRate
{
get
{
return flatRate;
}
set
{
flatRate = value;
}
}
}
History constraint (the "history rule").
This one is the same as the last rule. It states that the subtype should not introduce methods that mutate an immutable property in the parent class, such as adding a new Set method in a subclass to a property that once was only settable through the constructor.
An example:
public class Parent
{
protected int a;
public Parent(int a)
{
this.a = a;
}
}
public class Child : Parent
{
public Child(int a) : base(a)
{
this.a = a;
}
public void SetA(int a)
{
this.a = a;
}
}
Now, a previously immutable property in the parent class is now mutable, thanks to the subclass. That is also a violation of the LSP.
Do you know the ICollection interface?
Imagine you are writing a method that gets ICollection and manipulate it by using its Add method or better yet its Clear method
If someone passes an ReadOnlyCollection (that implements ICollection) you'll get an exception for using Add.
Now you would never expect that since the interface defines that is ok therefore the ReadOnlyCollection violated LSP.
I am trying to understand SOLID principles. I think I understand well the Liskov Substitution Principle, but I have some problems for other ones.
One example. I have two interfaces : Engine and car stereo.
The problem is : For a car, we have 6 glasses.
So, my car implements interfaces Engine and Car Stereo.
But for the 6 glasses, should I implement them, or should I put them on an array of glasses knowing there are 4 laterals glasses which are able to be up or down and 2 windshields (glasses inherited by both).
The problem with the first one is, I can't implement 4 times the same glasses.
So the second one seems to me good but I am afraid that break SRP, I am not sure to understand what "Responsibilities" exactly are.
The correct design practise is to
code to interface rather than class.
In light of this principle I'd recommend to use a interfaces like IWindow, ISurface, IWindShield with a hierarchy like below
interface ISurface
{
//surface specific properties which ideally should be DI-ed
public SurfaceType SurfaceType {get; set;}
public decimal Opacity {get;set;}
public decimal Thickness {get; set;}
}
and
interface IWindow:ISurface
{
//Window behavior specific properties and methods
public void lowerWindow();
public WindowHeight WindowLevel(){get;set;}
public void shutWindow();
// ...and more such window specific behavior
}
and
interface IWindShield:ISurface
{
//WindShield behavior specific properties and methods
public bool IsFogged(){get;set;}
public bool IsClean(){get;set;}
// ...and more such window specific behavior
}
Finally when assembling a car with all its functionality (presumably using a Builder pattern), you can have an array in the Car class of type ISurface type like below
class Car
{
string carName;
Engine carEngine;
Stereo carStereo;
List<ISurface> carGlasses;
.....
// other Car parts
// this is a typical builder pattern example
}
this is build using a CarBuilder type class say MyCarBuilder where
interface CarBuilder
{
public Car MyCar {get; set;}
void AddEngine();
void AddStereo();
void AddGlasses();// this is what works on adding ISurface List items
// and other car building methods
}
and the real builder class
class MyCarBuilder:CarBuilder
{
//... implements all methods of building your custom car
}
It really depends on intended use, but lets take car functional domain (invented on the spot) for example.
Your implementation class will implement IMotor (Tesla D has two motors), IEntertainmentCentre (lets hope there is one), IGlassSurface (could be quite a number in SUV). In each interface you will specify which motor/glass-surface you are addressing, for example: IGlassSurface.Operate(glassSurfaceId, direction, distance).
Possibly bad practice but I'm not well versed in software design anyway (I'm sure this question would have been asked before but I can't seem to find the right terminology)...Anyhow, it's just another curiosity of mine I'd like to have answered.
So I have worked in a way where I type a base class variable to type Object or Sprite or something similar so that in my subclasses, I can instantiate my custom classes into them and store it. And when I access it, I just cast that variable to ensure I can access the methods.
Take this example, so that you know what I'm talking about:
public class BaseClass
{
protected var the_holder_var:Object;
public function BaseClass()
{
//Whatever abstract implementation here...
}
}
Now, my subclasses of that base class usually use an interface but for simplicity sake, I'll just write it without it.
public class AnExtendedClass extends BaseClass
{
public function AnExtendedClass()
{
//Instantiate my own class into the base class variable
this.the_holder_var = new ACustomClassOfMine();
//Then I can use the 'hackish' getter function below to
//access the var's functions.
this.holder_var.somefunction()
}
private function get holder_var():ACustomClassOfMine
{
return this.the_holder_var as ACustomClassOfMine;
}
}
This works and I'm sure it will make some ppl cringe (I sometimes cringe at it too).
So now, my question, is there a way to recast/retype that base var in my extended subclass?
kinda like this:
public class ExtendedClass extends BaseClass
{
//Not possible I know, but as a reference to see what I'm asking about
//Just want to change the type....
override protected var the_holder_var:ACustomClassOfMine;
public function ExtendedClass()
{
//Then I can forget about having that hackish getter method.
this.the_holder_var = new ACustomClassOfMine();
this.the_holder_var.somefunction();
}
}
I was thinking of typing most of my base class vars that I use as holders as type * and retyping them as I extend the class. (I could use it here too but yeah...)
Thoughts? Comments? Ideas?
I actually think your code (apart from the hypothetical addition at the end) is pretty alright. The practise of adding accessors to solve the type issue you're dealing with is a solid one. I would advise to rename the accessor to show it is a cast, maybe get holderVarAsCustom():ACustomClassOfMine (I'm also not a big fan of the underscores, that's another language's convention), but that's personal preference. What I'd do to solve your last problem is just create a matching setter function:
private function set holderVarAsCustom(value:ACustomClassOfMine):void {
this.the_holder_var = value;
}
This way you can access the correctly typed holder var for both read and write operations with complete type safety:
holderVarAsCustom = new ACustomClassOfMine();
holderVarAsCustom.someFunction();
I would definately advise against dropping the type safety by including arrays and what not, that just makes it unstable.
I must admit that i'm a little confused as to why you want to do this, but here goes. Could you not utilise the fact that Array's can hold different data types. So something like this:
public class BaseClass
{
protected var customStorage:Array;
public function BaseClass()
{
//Whatever abstract implementation here...
}
}
You could then access it with an associative method and a property:
public class AnExtendedClass extends BaseClass
{
private static const myName:String = "myName";
public function AnExtendedClass()
{
//Instantiate my own class into the base class variable
customStorage[myName] = new ACustomClassOfMine();
objectIWant.somefunction()
}
private function get objectIWant():ACustomClassOfMine
{
return ACustomClassOfMine(customStorage[myName]);
}
}
Is that any better?
I would not try to tinker this behaviour, since you can't change the declared type of a variable once declared, no matter how hard you try.
What I do in such cases, I either cast the variable if I use it sparingly or the object it references may change, or I add another variable with the type I want and let the other variable point to the new one. Like this:
public class A {
protected var object:Object;
public function A() {
//Whatever abstract implementation here...
}
}
and
public class B extends A {
protected var other:MyClass;
public function B() {
super();
this.other = new MyClass();
this.object = this.other;
}
}
Having it this way, class A uses the object via the this.object reference, and class B can use the this.other or both. But both references point to the same object. The only issues with this are:
having two references for in the same class to the same object is ugly (so are untyped variables and casts)
if the object one of them may point can change during runtime, you must be really carefull to synchronize these changes
I'm working through the book Head First C# (and it's going well so far), but I'm having a lot of trouble wrapping my head around the syntax involved with using the "this." keyword.
Conceptually, I get that I'm supposed to use it to avoid having a parameter mask a field of the same name, but I'm having trouble actually tracking it through their examples (also, they don't seem to have a section dedicated to that particular keyword, they just explain it and start using it in their examples).
Does anyone have any good rules of thumb they follow when applying "this."? Or any tutorials online that explain it in a different way that Head First C#?
Thanks!
Personally I only use it when I have to which is:
Constructor chaining:
public Foo(int x) : this(x, null)
{
}
public Foo(int x, string name)
{
...
}
Copying from a parameter name into a field (not as common in C# as in Java, as you'd usually use a property - but common in constructors)
public void SetName(string name)
{
// Just "name = name" would be no-op; within this method,
// "name" refers to the parameter, not the field
this.name = name;
}
Referring to this object without any members involved:
Console.WriteLine(this);
Declaring an extension method:
public static TimeSpan Days(this int days)
{
return TimeSpan.FromDays(days);
}
Some other people always use it (e.g. for other method calls) - personally I find that clutters things up a bit.
StyleCop's default coding style enforces the following rule:
A1101: The call to {method or property
name} must begin with the 'this.'
prefix to indicate that the item is a
member of the class.
Which means that every method, field, property that belongs to the current class will be prefixed by this. I was initially resistant to this rule, which makes your code more verbose, but it has grown on me since, as it makes the code pretty clear. This thread discusses the question.
I write this. if and only if it enhances readability, for example, when implementing a Comparable interface (Java, but the idea is the same):
public void compareTo(MyClass other) {
if (this.someField > other.someField) return 1;
if (this.someField < other.someField) return -1;
return 0;
}
As to parameter shadowing (e.g. in constructors): I usually give those a shorter name of the corresponding field, such as:
class Rect {
private int width, height;
public Rect(int w, int h) {
width = w;
height = h;
}
}
Basically, this gives you a reference to the current object. You can use it to access members on the object, or to pass the current object as parameters into other methods.
It is entirely unnecessary in almost all cases to place it before accessing member variables or method calls, although some style guidelines recommend it for various reasons.
Personally, I make sure I name my member variables to be clearly different from my parameters to avoid ever having to use 'this.'. For example:
private String _someData;
public String SomeData
{
get{return _someData;}
set{_someData = value;}
}
It's very much an individual preference though, and some people will recommend that you name the property and member variable the same (just case difference - 'someData' and 'SomeData') and use the this keyword when accessing the private member to indicate the difference.
So as for a rule of thumb - Avoid using it. If you find yourself using it to distinguish between local/parameters variables and member variables then rename one of them so you don't have to use 'this'.
The cases where I would use it are multiple constructors, passing a reference to other methods and in extension methods. (See Jon's answer for examples)
If you have a method inside a class which uses same class's fields, you can use this.
public class FullName
{
public string fn { set; get; }
public string sn { set; get; }
//overriding Equals method
public override bool Equals(object obj)
{
if (!(obj is FullName))
return false;
if (obj == null)
return false;
return this.fn == ((FullName)obj).fn &&
this.sn == ((FullName)obj).sn;
}
//overriding GetHashCode
public override int GetHashCode()
{
return this.fn.GetHashCode() ^ this.sn.GetHashCode();
}
}
Currently I can think of only three good reasons to return this in a (public) method, namely:
(mmyers) when implementing fluent interfaces, e.g.
public class X
{
...
public X enableValidation()
{
setValidation(true);
return this;
}
...
}
(Jon Skeet) for identity conversions, e.g.
public class X
{
...
public X toX()
{
return this;
}
...
}
(Dave Ray) implementing a clone() or copy() method on an immutable object, e.g.
#Immutable
public class X
{
...
public X copy()
{
return this;
}
...
}
Are there any other useful scenarios in an object-oriented language in which you would return this or self from a method?
If you are creating chaining operations (however this might not be very OOP'ish - Law of Demeter, etc).
Example (not that it makes a lot of sense):
public class X
{
public X Add(int i)
{
this.Value += i;
return this;
}
public X Subtract(int i)
{
this.Value -= i;
return this;
}
public int Value
{
get;
set;
}
}
new X().Add(4).Subtract(5).Value;
String.toString() :)
On a more serious note, there are similar "convert to [x]" scenarios where it's okay to just return "this"... but I can't think of very many other situations.
Any implementation of a clone() or copy() method on an immutable object.
C++ does this all the time to allow cascading operators.
for example the << operator always returns itself (ostream) so that you can cascade the calls in such a way:
std::cout << "call 1" << "call2" << std::endl;
The only language which I believe this cascading effect is popular is C++.
Quick addition when it comes to fluent interfaces:
As mentioned in this "A simple example of a fluent interface" article (at the end of the comments), :
You'll hit a brick when using inheritance along with fluent interfaces because:
using polymorphic methods break your call chains and
you definitely don't want to make your interfaces non-fluent by using ugly casting and parenthesis where they are not needed or by doing lots of un-useful overrides in the children that do the casting
alt text http://withasmiletomeltathousandhearts.files.wordpress.com/2009/02/fluent_interfaces_order_class_hierarchy.jpg?w=300&h=255
In this article about a more robust pattern for complex (and yet fluent) hierarchy of classes , "this" is used to return the instance of the base class "Builder", whereas Builder for concrete classes uses casting.
Take the following implementation.
public interface Monitorable {
public Statistics getStatistics();
}
public interface MonitorManager {
public Monitorable getMonitorable();
}
class MonitorableService implements Monitorable, MonitorManager {
public Monitorable getMonitorable() {
return this;
}
}
// Meanwhile somwhere else...
MonitorManager manager = getMonitorManagerFromSomewhere();
Monitorable monitorable = manager.getMonitorable();
I admit this is rather contrived, but the overal pattern/message should be clear.
Here I do not need to know the MonitorManager is implemented by the Application class. Nor do I need to know that Monitorable is implemented by Application.
Here polymorphism is used to encapsulate the implementation details of Application. Which is not a public class. This is a very common pattern, and can be seen in a wide variety of projects.