Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

When I design classes and have to choose between inheritance and composition, I usually use the rule of thumb: if the relationship is "is-a" - use inheritance, and if the relationship is "has-a" - use composition.

Is it always right?

Thank you.

like image 847
Igor Avatar asked Jan 17 '09 18:01

Igor


People also ask

Is composition is a or has a?

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.

What is inheritance and composition?

Inheritance and composition are two programming techniques developers use to establish relationships between classes and objects. Whereas inheritance derives one class from another, composition defines a class as the sum of its parts.

What is is a and has a relationship?

It is also used for code reusability in Java. In Java, a Has-A relationship simply means that an instance of one class has a reference to an instance of another class or an other instance of the same class. For example, a car has an engine, a dog has a tail and so on.

Can you have inheritance and composition?

In most cases, composition can be used interchangeably with inheritance. One thing that makes inheritance so well-known is polymorphism. Composition is initially not designed for polymorphism. But most programming languages allow us to do that with interfaces (known as protocols in the Swift world).


1 Answers

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

like image 172
Sir Rippov the Maple Avatar answered Sep 26 '22 06:09

Sir Rippov the Maple