That’s what I always say, object orientation is poorly defined and depends on who defines (see).
You will find that heritage is to be reused in various places and I am not talking about random internet sources.
The heritage we use in practice is part of two things: subtype inheritance and implementation inheritance (also).
The subtype part has to do with contracts. In general we talk about the explicit contracts that are the signatures that we see in the code, but the expected (semantic) result is still a contract. All this has to do with Liskov. This principle says that the child type should do everything the parent type does. The detail may even change, but the way to use and the result may not.
To abstraction is to say what the guy will do in general terms, give a basis of what needs to be delivered without giving all the details that will be given in a specialized way. It can give implementation that will be reused.
When you extend a class is reusing what already has there to do something a little more specialized.
The implementation part is the reuse part. Without reuse, there is no point in having inheritance, unless you just want the subtype. Some people think this is secondary and perhaps for this reason preach that it is not the goal.
If inheritance occurs only in the subtype then using interface in a class is inheritance? There are controversies. Interface is only contract, has no implementation (have been misrepresenting this, but within normal). If it is inheritance why languages use implements
and not inherits
when you use it?
Dynamic typing language doesn’t care so much about contracts, so it doesn’t care so much about subtype compliance. So dynamic typing languages have no inheritance?
It can be said that it is not the main one, but it cannot be said that the reuse is not an objective.
At the same time the reuse can be obtained with other forms other than inheritance.
You can’t force Liskov completely by code, but what gives can do only with interface.
To create an abstraction you can use the interface.
If you take the reuse out of the equation the interface is enough to define inheritance. Some people think so and say that there should only be an interface. People can think what they want, but it has valid justification?
Some people say that for reuse it should import an implementation privately, it should be detached from the subtype, in general by mixin (also) or some mechanism that produces the same effect. But why can’t it have both? Most OO languages disagree with these people and do both.
If you take away the reuse, the inheritance as it is commonly used, ceases to exist altogether and leaves for the composition or delegation as reuse mechanism. There is a case that should be really so, and living defending, but has case for inheritance, reusing what already exists.
Only care is needed because people abuse and see reuse by inheritance, generalization where it does not exist. An example I always quote is that Cliente
or Aluno
is not specialization of Pessoa
. This is the wrong reuse, and that "everyone" who defends purity of OO, who says that not inheritance is not about reuse, errs precisely by practicing reuse for heritage where should not, the right there is the composition.
I believe polymorphism is the most legitimate reason to create a class hierarchy.
– epx
This answers your question? It is wrong to use class inheritance to group common behaviors and attributes?
– Dherik