| People are overthinking this. In practice inheritance is a very special case of composition that is only advantageous in a very narrow set of usecases. Basically almost never. In fact the number of usecases is so low that I would prefer that modern languages just omit it entirely because the added value is incredibly tiny compared to the cost of confused developers. The primary difference between an interface and inheritance is that with inheritance you do not have to implement every method and can use the default implementation of the base class. Example: class Piece {
int x
int y
boolean validMove(int newX, int newY) {
return false;
}
}
class Queen extends Piece {
boolean validMove(int newX, int newY)
//we use the default implementation
}
Is equivalent to this interface IPiece {
boolean validMove(int newX, int newY);
}
class Piece() implements IPiece {
int x
int y
boolean validMove(int newX, int newY) {
return false;
}
}
class Queen implements IPiece {
Piece piece;
boolean validMove(int newX, int newY) {
//we use the default implementation
return piece.validMove(newX, newY);
}
}
Inheritance doesn't actually offer any code reuse. All it does is choose the default implementation of the parent class. If you have dozens of polymorphic functions in a class and only want to change 3 it might be convenient. I would question why you need so much polymorphism to warrant a special language feature. C and Rust developers are fine without it. Functional programmers are fine without it. But for some reason in OOP you need it everywhere and are actually worse off because it's overused.Modern language designers, please do not implement inheritance of classes in your new languages! |
You are confused. See my other message below where I show that composition and inheritance are not mutually exclusive (and arguably, the best of both worlds is using inheritance via composition).