Are there any good tips, when one should subclass and when should not?
It’s clear that we should not subclass when
- we want to reuse a single method of some class
- we override all methods, changing the behavior of superclass completely.
But in real life, it’s more difficult to decide. For example, I have a BasicToolbar
class, which has several buttons arranged on a panel. There is a second class ExtendedToolbar
, which hould
- have some additional buttons
- change the ordering of all buttons
- on condition hide/remove a couple of buttons from parent class
I tend to subclass to reuse those buttons and override ordering/addition logic, but occasional removing of a button of the parent class seem to be against idea of inheritance.
Any opinion is welcome.
8
The Liskov Substiution Principle is by far the best “heuristic” I know of for determining whether direct subclassing is a good idea.
Say you have a base class Foo, and derived classes Bar1 through Bar9. In a nutshell, the LSP states that any block of code using a Foo must work correctly no matter which of the nine Bar types that Foo actually is.
From the user’s point of view, that means code using the base class should be able to work almost exclusively with that base class, without caring what the actual type of the object is.
From the implementer’s point of view, that means each subclass must implement the full interface of the base class, including all of the implied semantic properties, without any surprises or additional restrictions.
If the subclass you’re thinking of writing won’t follow these rules, that’s a very strong indication you should not be using inheritance.
Regarding your toolbar example, I don’t think it makes a lot of sense to use inheritance that way. I’d rather have Button classes, a generic Toolbar class that can contain any arrangement of Buttons, and then make BasicToolbar and ExtendedToolbar be objects with a Toolbar member that they add Buttons to in their constructors. If they share a bunch of buttons, make BackButton/LikeButton/UpvoteButton classes with a Button member, and let the Toolbars contain them. Using inheritance anywhere in this arrangement will only add unnecessarily tight restrictions on how you can rearrange these classes in the future.
2
It depends on the conventions and guidelines for a specific programming language. In C# it is not easy to delegate methods to an inner object (it requires explicit code). So inheritance can be easier. When creating a public .net based API, inheritance is often recommended, to simplify discovery for the API user.
One common use is when you want to use the template method pattern.
I that pattern you write the skeleton of an algorithm in an abstrac class. In some parts of that skeleton you can certain methods that are not implemented.
Subclassed implement those methods completing the algorithm. That can also be achieved without inheritance using injection and or delegates.
In general you should not subclass where there is not “is a” relationship between class.
Another patter that uses inheritance is the decorator patter which is similar to the toolbar example you gave.