A composição sobre herança (ou princípio de reutilização composto) na programação orientada a objeto (OOP)
é o princípio de que classes devem alcançar comportamento polimórfico e reutilização de código por sua composição
(contendo instâncias de outras classes que implementam a funcionalidade desejada) em vez de herança de um classe base ou pai.
Este é um princípio frequentemente afirmado de OOP, como no influente livro Design Patterns.
Composição é a forma mais forte de associação, o que significa que o(s) objeto(s) que compõem ou estão contidos
em um objeto são destruídos também quando esse objeto é destruído.
Exemplo
Herança
class Vehicle {
public String getDetails() {
return "This is vehicle details";
}
}
class Car extends Vehicle {
}
Composition
public VehicleDetails getDetails() {
VehicleDetails vehicleDetails = new VehicleDetails();
vehicleDetails.setDetails("This is vehicle details");
return vehicleDetails;
}
class Car {
Vehicle vehicle = new Vehicle();
public String getDetails() {
VehicleDetails vehicleDetails = vehicle.getDetails();
return vehicleDetails.getDetails();
}
}
Note que no exemplo de Composition, se quisermos nos utilizar de Herança, o código da classe Car irá quebrar,
pois, ela espera uma String em getDetails.
Com a Herança, você é forçado a usar toda a interface da classe mãe, já com Composition você tem maior maleabilidade.
Além disso, a Herança pode introduzir alguns problemas de dependência entre as classes herdadas.
fontes:
https://www.baeldung.com/java-inheritance-composition
http://sudotutorials.com/tutorials/java/basics/java-composition.html
https://medium.com/@cscalfani/goodbye-object-oriented-programming-a59cda4c0e53