Inheritance or Composition: Rely on "Is-A" and "Has-A"

Inheritance or composition: Rely on is-a and has-a ?

No - "is a" does not always lead to inheritence. A well cited example is the relationship between a square and a rectangle. A square is a rectangle, but it will be bad to design code that inherits a Square class off a Rectangle class.

My suggestion is to enhance your "is a / has a" heuristic with the Liskov Substitution Principle. To check whether an inheritence relationship complies with the Liskov Substitution Principle, ask whether clients of a base class can operate on the sub class without knowing that it is operating on a sub class. Of course, all the properties of the sub class must be preserved.

In the square / rectangle example, we must ask whether a client of rectangle can operate on a square without knowing that it is a square. All that the client must know is that it is operating on a rectangle. The following function demonstrates a client that assumes that setting the width of a rectangle leaves the height unchanged.

void g(Rectangle& r)
{
r.SetWidth(5);
r.SetHeight(4);
assert(r.GetWidth() * r.GetHeight()) == 20);
}

This assumption is true for a rectangle, but not for a square. So the function cannot operate on a square and therefore the inheritence relationship violates the Liskov Substitution principle.

Other examples

What is the difference between IS -A relationship and HAS-A relationship in Java?

An IS-A relationship is inheritance. The classes which inherit are known as sub classes or child classes. On the other hand, HAS-A relationship is composition.

In OOP, IS-A relationship is completely inheritance. This means, that the child class is a type of parent class. For example, an apple is a fruit. So you will extend fruit to get apple.

class Apple extends Fruit {

}

On the other hand, composition means creating instances which have references to other objects. For example, a room has a table.
So you will create a class room and then in that class create an instance of type table.

class Room {

Table table = new Table();

}

A HAS-A relationship is dynamic (run time) binding while inheritance is a static (compile time) binding.
If you just want to reuse the code and you know that the two are not of same kind use composition. For example, you cannot inherit an oven from a kitchen. A kitchen HAS-A oven.
When you feel there is a natural relationship like Apple is a Fruit use inheritance.

Difference between Inheritance and Composition

They are absolutely different. Inheritance is an "is-a" relationship. Composition is a "has-a".

You do composition by having an instance of another class C as a field of your class, instead of extending C. A good example where composition would've been a lot better than inheritance is java.util.Stack, which currently extends java.util.Vector. This is now considered a blunder. A stack "is-NOT-a" vector; you should not be allowed to insert and remove elements arbitrarily. It should've been composition instead.

Unfortunately it's too late to rectify this design mistake, since changing the inheritance hierarchy now would break compatibility with existing code. Had Stack used composition instead of inheritance, it can always be modified to use another data structure without violating the API.

I highly recommend Josh Bloch's book Effective Java 2nd Edition

  • Item 16: Favor composition over inheritance
  • Item 17: Design and document for inheritance or else prohibit it

Good object-oriented design is not about liberally extending existing classes. Your first instinct should be to compose instead.


See also:

  • Composition versus Inheritance: A Comparative Look at Two Fundamental Ways to Relate Classes

java IS-A relationship exam question confusion

Your rationale is slightly off, as this relationship applies to classes, not to objects.

A string IS-A object since String inherits from Object. Similarly a FileOutputStream IS-A OutputStream IS-A Object.

IS-A is a relationship between classes, no between classes and objects.

Inheritance vs Composition: Does composition effectively solve dependency issues? [Effective Java]

Ok so I looked up what @LeiYang recommended and came to realize the my question wasn't valid. The given paragraph states "a subclass depends on the implementation details of its superclass for its proper function" - which Object Composition would have no problem with, as it merely makes use of provided methods as is(without overriding). Therefore Object Composition doesn't violate encapsulation and is relatively stable compared to Inheritance.

Using both Inheritance and Composition in the same class?

They are not mutually exclusive. Example: Boat and Sailboat. Sailboat is-a Boat, but it has-a Sail, which other Boats may or may not have.



Related Topics



Leave a reply



Submit