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.