Usando herança:
1- Ao usar herança estamos violando um dos pilares da orientação a objetos: o encapsulamento, visto que os detalhes da implementação da classe Pai são expostos nas classes Filhas;
2- Ao usar herança estamos violando um dos princípios básicos das boas práticas de programação : manter o acoplamento entre as classe fraco, visto que as classes filhas estão fortemente acopladas à classe Pai e alterar uma classe Pai pode afetar todas as classes Filhas;
3- As implementações herdadas da classe Pai pelas classes Filhas não pode ser alteradas em tempo de execução;
Usando composição
1- Os objetos que foram instanciados e estão contidos na classe que os instanciou são acessados somente através de sua interface;
2- A composição pode ser definida dinamicamente em tempo de execução pela obtenção de referência de objetos a objetos de do mesmo tipo;
3- A composição apresenta uma menor dependência de implementações;
4- Na composição temos cada classe focada em apenas uma tarefa (princípio SRP);
5- Na composição temos um bom encapsulamento visto que os detalhes internos dos objetos instanciados não são visíveis;