1
resposta

Herança e o princípio de Liskov

Não é certamente uma dúvida, mas uma opinião. Tenho gostado bastante das aulas de SOLID mas, no meu entendimento, faltou ao exemplo utilizado nessa aula demonstrar como solucionar o problema apresentado no início, que era gerar o rendimento para todas as contas. Em minha opinião, a herança funcionaria muito bem no caso inicial, usando as restrições citadas (não afrouxar requisitos de saída e não restringir os de entrada) bastando gerar um rendimento nulo para o caso da conta de estudante. Entendo que foi apenas um exemplo. Substituição por composição é interessante em diversos casos, como o exemplo que foi dado no início do curso, na Calculadora de Salário com a substituição a seguir:

    public double calculaSalario() {
        return getCargo().getRegra().calcula(this);
    }

onde o cálculo do salário na utilização da classe Funcionário substituiu o encadeamento de chamadas. Compor é interessante mas gera, muitas vezes, uma necessidade de sair replicando código nas classes que o compõem para refletir comportamentos que, com a herança, seriam mais fáceis de implementar. No caso ilustrado, seria necessário ter duas listas, uma de contas de estudantes e outra de contas comuns. Caso outro tipo de conta surja, outra lista deve ser criada. Tudo bem que isso poderia ser feito com o uso de interfaces para cálculos que processassem todas as contas, mas a separação em listas me incomoda de certa forma. Bem, eu gosto de usar herança. Com cuidado, obviamente.

1 resposta

Prefira a composição à herança, pois é mais maleável / fácil de modificar posteriormente, mas não use composição sempre. A herança é mais rígida, pois a maioria das linguagens não permite derivar de mais de um tipo.

Desvantagens da herança:

Você não pode alterar a implementação herdada das superclasses no tempo de execução (obviamente porque a herança é definida no tempo de compilação). A herança expõe uma subclasse aos detalhes de sua implementação de classe pai, é por isso que muitas vezes se diz que a herança quebra o encapsulamento (no sentido de que você realmente precisa se concentrar nas interfaces, não na implementação, portanto, nem sempre é preferível a reutilização pela subclasse). O acoplamento rígido fornecido pela herança torna a implementação de uma subclasse muito ligada à implementação de uma superclasse que qualquer alteração na implementação pai forçará a subclasse a mudar. A reutilização excessiva por subclassificação pode tornar a pilha de herança muito profunda e muito confusa também.