É correto dar maior preferência a composição do que herança?

Sim, é geralmente recomendado dar mais preferência à composição do que à herança ao projetar sistemas de software. A herança ocorre quando uma classe herda atributos e comportamentos de uma classe pai, enquanto a composição envolve a criação de objetos com base em outros objetos existentes.

Existem algumas razões pelas quais a composição pode ser preferível à herança:

  1. Flexibilidade: A composição permite que você altere o comportamento de um objeto, substituindo-o por outro objeto compatível. Isso torna mais fácil estender e modificar o comportamento de um objeto sem afetar outras partes do sistema. Por outro lado, a herança cria uma relação mais rígida entre as classes, o que pode dificultar a flexibilidade e a manutenção do código.

Por exemplo, suponha que você tenha uma classe “Veículo” e uma subclasse “Carro”. Se você decidir adicionar funcionalidades específicas para carros elétricos, é mais fácil encapsular essas funcionalidades em uma classe separada “MotorEletrico” e compor um objeto “MotorEletrico” dentro da classe “Carro” do que criar uma nova subclasse “CarroEletrico”.

  1. Acoplamento fraco: A composição pode ajudar a reduzir o acoplamento entre classes, o que é desejável porque classes fracamente acopladas são mais independentes e podem ser modificadas sem afetar outras partes do código. Em contraste, a herança tende a aumentar o acoplamento, pois alterações na classe pai podem afetar imediatamente todas as subclasses.

Por exemplo, se você tiver uma classe “Animal” com subclasses “Cachorro” e “Gato”, qualquer alteração na classe “Animal” terá um impacto direto nas subclasses. No entanto, se você usar a composição, pode ter uma classe separada “Comida” e compor um objeto “Comida” dentro das classes “Cachorro” e “Gato”. Isso permite que você faça alterações na classe “Comida” sem afetar diretamente as subclasses.

  1. Reutilização de código: A composição pode facilitar a reutilização de código porque você pode criar e usar objetos separados em várias partes do sistema. Qualquer lógica comum pode ser encapsulada em um objeto separado e usado em várias classes. Isso promove uma abordagem modular e facilita a manutenção e evolução do código.

Em suma, a composição oferece mais flexibilidade, menor acoplamento e maior reutilização de código em comparação com a herança. Claro, há casos em que a herança pode ser a abordagem mais apropriada, mas, em geral, a composição é preferível.