Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where does idea that "inheritance is to be avoided" originate from? [closed]

Recently we discussed a defect mentioned here and one of the parties said something like "yes, that's why books say that inheritance should be avoided.

I've been using inheritance for years and find it very useful and convenient in many design cases. Also I'm sure that the person arguing at the very least misunderstood what those "books say".

Is there really an idea that inheritance is kind of bad and should be avoided? Where does it originate and where can I learn more?

like image 874
sharptooth Avatar asked Feb 09 '11 14:02

sharptooth


4 Answers

I think what he might have meant is that inheritance can be overused, even in cases where composition would be a better solution. This is discussed in several books, e.g.

  • Effective Java 2nd Edition, Item 16: Favor composition over inheritance

Inheritance is a powerful way to achieve code reuse, but it is not always the best tool for the job. Used inappropriately, it leads to fragile software. It is safe to use inheritance within a package, where the subclass and the superclass implementations are under the control of the same programmers. It is also safe to use inheritance when extending classes specifically designed and documented for extension (Item 17). Inheriting from ordinary concrete classes across package boundaries, however, is dangerous. As a reminder, this book uses the word “inheritance” to mean implementation inheritance (when one class extends another). The problems discussed in this item do not apply to interface inheritance (when a class implements an interface or where one interface extends another).

Unlike method invocation, inheritance violates encapsulation [Snyder86]. In other words, a subclass depends on the implementation details of its superclass for its proper function. The superclass’s implementation may change from release to release, and if it does, the subclass may break, even though its code has not been touched. As a consequence, a subclass must evolve in tandem with its superclass, unless the superclass’s authors have designed and documented it specifically for the purpose of being extended.

  • Effective C++ 3rd Edition has several items related to this:
    • Item 32: Make sure public inheritance models "is-a."
    • Item 34: Differentiate between inheritance of interface and inheritance of implementation
    • Item 38: Model "has-a" or "is-implemented-in-terms-of" through composition
like image 115
Péter Török Avatar answered Sep 28 '22 03:09

Péter Török


Not to be avoided every time, but it hinders flexibility wherever you are stuck with a defined set of operations from a superclass. The basic design idea is "leave to inheritance the fixed parts and inject the parts subject to change".

In Head First Desing Patterns there is a good example.

Say you decide to model ducks with a base class which implements fly(). Say that you have a RubberDuck, who can't fly, of course. You override fly() with a method that does nothing. But then some day you add DecoyDuck and forget to override fly() and you get a mess. It would have been better to build the DecoyDuck injecting the desired behaviour (composition over inheritance).

like image 38
Manrico Corazzi Avatar answered Sep 28 '22 03:09

Manrico Corazzi


Good coding practice in C++ prefers composition through aggregation. cf. "C++ Coding Standards: 101 Rules, Guidelines, And Best Practices" by Sutter/Alexandrescu

like image 29
Stephane Rolland Avatar answered Sep 28 '22 02:09

Stephane Rolland


Inheritance should not be avoided 'as is'.
Inheritance should be used (and only used) when you want to define / describe an 'is a' relationship.

When an entity 'is not' anotherentity, entity should not inherit from anotherentity. In such cases, composition should be used.

like image 40
Frederik Gheysels Avatar answered Sep 28 '22 02:09

Frederik Gheysels