I was reading about NonVirtual Interface pattern: Herb Sutter is talking about why virtual function must be private in most of the case, protected in some case and never pub
You could buy a copy of More Effective C++, or check your local library for a copy, and read item 33 for the full explanation. The explanation given there is that it makes your class prone to partial assignment, also known as slicing:
There are two problems here. First, the assignment operator invoked on the last line is that of the
Animal
class, even though the objects involved are of typeLizard
. As a result, only theAnimal
part ofliz1
will be modified. This is a partial assignment. After the assignment,liz1
'sAnimal
members have the values they got fromliz2
, butliz1
'sLizard
members remain unchanged.The second problem is that real programmers write code like this. It's not uncommon to make assignments to objects through pointers, especially for experienced C programmers who have moved to C++. That being the case, we'd like to make the assignment behave in a more reasonable fashion. As Item 32 points out, our classes should be easy to use correctly and difficult to use incorrectly, and the classes in the hierarchy above are easy to use incorrectly.
See this question and others for a description of the object slicing problem in C++.
Item 33 also says this, later on:
Replacement of a concrete base class like
Animal
with an abstract base class likeAbstractAnimal
yields benefits far beyond simply making the behavior ofoperator=
easier to understand. It also reduces the chances that you'll try to treat arrays polymorphically, the unpleasant consequences of which are examined in Item 3. The most significant benefit of the technique, however, occurs at the design level, because replacing concrete base classes with abstract base classes forces you to explicitly recognize the existence of useful abstractions. That is, it makes you create new abstract classes for useful concepts, even if you aren't aware of the fact that the useful concepts exist.
When you derive from a concrete base class you inherit functionality, which may not be revealed to you if you do not have the source code. When you program to an interface (or abstract class) you don't inherit functionality meaning it it a better way to do things like expose an API. That being said I think that there are plenty of times when inheriting from a concrete class is acceptable
A problem with inheriting from a concrete type is that it creates some ambiguity as to whether code which specifies a certain type really wants an object of the specific concrete type, or wants an object of a type which behaves in the fashion that the concrete type behaves. This distinction is vital in C++, since there are many cases where operations which will work correctly on objects of a certain type will fail badly on objects of derived types. In Java and .NET, there are many fewer situations where one can use an object of a particular type, but could not use an object of a derived type. As such, inheriting from a concrete type isn't nearly as problematical. Even there, however, having sealed concrete classes which inherit from abstract classes, and using the abstract class types everywhere except in constructor invocations (which must use the concrete types) will make it easier to change parts of the class hierarchy without breaking code.
I think this is because concrete class has concrete behavior. When deriving from it, you are committed to retain the same "contract", but the actual contract is defined by the specific implementation of the base class, and in reality will have many subtleties you will probably break without knowing.
Disclaimer: I am not an experienced developer; it is just a suggestion.
In general, it's difficult to strictly maintain a contract between two distinct concrete objects.
Inheritance becomes really easier and more robust when we deal with generic behavior.
Imagine that we want to create a class named Ferrari
and a subclass named SuperFerrari
.
Contract is: turnTheKey()
, goFast()
, skid()
At first glance, sounds like very similar class, with no conflict. Let's go with inheritance of these both concrete classes.
However, now we want add a feature to SuperFerrari
: turnOnBluRayDisc()
.
Problem: Inheritance expects a IS-A relationship between components. With this new feature, SuperFerrari
is not a simple Ferrari
any more with its own behavior; it now ADDS behavior .
It would lead to some ugly code, with some cast needed, in order to choose the new feature while dealing with a Ferrari
reference initially (polymorphism).
With an abstract/interface class in common to both classes, this problem would disappear since Ferrari
and SuperFerrari
would be two leafs, and it's more logic since now Ferrari
and SuperFerrari
should not be consider as similar (not a IS-A relationship any more).
In short, derive from concrete class would lead in many cases to a poor/ugly code, less flexible, and hard to read and maintain.
Making a hierarchy driven by abstract class/interface allow concrete children classes to evolve separately without any issues, especially when you implement some subhierarchies dedicated to a special amount of concrete classes without boring others leafs, and still benefit from polymorphism.