I wrote this yesterday, in a class Foo inheriting from Bar:
public override void AddItem(double a, int b) { //Code smell? throw new NotImplementedException('This method not usable for Foo items'); }
Wondered subsequently if this is a possible indication that I should be using a Bar, rather than inheriting from it.
What other ‘code smells’ could help to chose between inheritance and composition?
EDIT I should add that this is a snippet, there are other methods which are in common, I just didn’t want to go into too much detail. I have to analyse the implications of switching to composition, and wondered if there might be other ‘code smells’ which could help to tip the balance.
The example you gave above is clearly a code smell. The
AddItemmethod is a behaviour of the base classBar. IfFoodoesn’t support theAddItembehaviour, it shouldn’t inherit fromBar.Let’s think of a more realistic (C++) example. Let’s say you had the following class:
The base abstract class
Animalprovides a pure virtualBreathe()method, because an animal must breathe to survive. If it doesn’t breathe, then by definition it is not an animal.By creating a new class
Dogwhich inherits fromAnimalbut doesn’t support theBreathe()behaviour, you are breaking the contract stipulated by theAnimalclass. The poor dog won’t survive!The simple rule for public inheritance is that you should only do it if the derived class object truly ‘is a’ base class object.
In your particular example:
Foodoesn’t support theAddItem()behaviour stipulated by theBarcontract.Foois ‘not a’Bar, and shouldn’t inherit from it.