Não se trata disso, simplesmente usar composição quando se deve usar herança não faz sentido pra mim.
O que é conhecido:
Herança: relacionamento é um; //tem mais uns poréns importantes, mas esta é a base
Composição: tem um;
Interface: se comporta como um.
Quanto a manutenção o que é mal feito vai dar trabalho de qualquer forma, seja com ou sem herança.
Particularmente, continuo achando arbitrário este posicionamento de usar composição quando se deve usar herança.
Não vou me ater ao caso do funcionário que é cliente e funcionário ao mesmo tempo, pois pessoalmente creio que a implementação da herança seria pessoa <- cliente <- funcionário e quanto ao cadastro um requisito não funcional resolveria a situação, mas isto é irrelevante.
Um caso semelhante seria de uma filha, que passa a ser mãe e depois para avó mantendo todos os seus atributos, não falo da identidade pois a definição e o debate sobre esta é bem mais complexa, tanto é que em um banco de dados usamos o “id”.
Embora haja outros fatores inerentes a herança, para o caso das Mulheres, filha que se torna mãe e depois avó eu preferi a herança, pois faz sentido desde que a classificação e ordem de herança seja a correta: Mulher <- Filha <- Mae <- Avo, neste caso.
A implementação a seguir é irrelevante, mas faz uso de Herança, Polimorfismo e Composição (nada novo).
import java.util.Arrays;
public class Teste {
public static void main(String[] args) {
Mulher ana = new Filha("Ana", 11),
maria = new Filha("Maria", 31),
joana = new Mae("Joana", 47);//mãe não precisaria informar os filhos
maria = new Mae((Filha) maria, (Filha) ana);//tornando filha em mãe, podendo usar o método estático familiarizar par mão da classe Mulher
joana = new Avo((Mae) joana, (Filha) maria);//tornando mãe em avó
System.out.println();
Arrays.asList(ana, maria, joana).forEach(mulher -> {
System.out.println(mulher.getNome() + " é mãe? [" + mulher.isMae()
+ "] classe -> " + mulher.getClass().getSimpleName()
+ (mulher.temMae() ? " ... Sendo filha de : " + ((Filha) mulher).getMae().getNome() : ""));
});
}
}
.
public abstract class Mulher {
protected String nome;
protected int idade;
public abstract boolean temMae();
public abstract boolean isMae();
public int getIdade() {
return idade;
}
public String getNome() {
return nome;
}
public static void familiarizarParaMae(Filha filha) {
filha = new Mae(filha.nome, filha.idade);
}
public static void familiarizarParaMae(Filha filha, Filha ... filhas) {
filha = new Mae(filha, filhas);
}
}
.
public class Filha extends Mulher{
private Mae mae;
protected boolean genitora;
public Filha(String nome, int idade) {
this.nome = nome;
this.idade = idade;
System.out.println(nome+" utilizando o contrutor da classe filha como: "+this.getClass().getSimpleName());
}
public Mae getMae() {
return mae;
}
public void setMae(Mae mae) {
this.mae = mae;
}
@Override
public boolean isMae() {
return genitora;
}
@Override
public boolean temMae(){
return this.mae != null;
}
}
.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Mae extends Filha {
private final List<Mulher> mulheres = new ArrayList<>();
public Mae(String nome, int idade) {
super(nome, idade);
this.genitora = true;
}
public Mae(Filha filhaQueSeTornaMae, Filha ... filhas) {
this(filhaQueSeTornaMae.nome, filhaQueSeTornaMae.idade);
Arrays.stream(filhas).forEach((Filha filha) -> {
mulheres.add(filha);
filha.setMae(Mae.this);
});
}
public List<Mulher> Descendentes(ArrayList<Mulher> filhas) {
return mulheres;
}
public void addDescendentes(Mulher mulher) {
mulheres.add(mulher);
}
}
.
public class Avo extends Mae {
public Avo(String nome, int idade) {
super(nome, idade);
}
public Avo(Mae maeQueSeTornaAvo, Filha... filhas) {
super(maeQueSeTornaAvo, filhas);
}
}
Sou grato pelo compartilhamento de experiências pois me agrada aprender e prever situações, mas neste caso me retiro singelamente da discussão não por que já foi resolvida, ou porque possa estar fugindo de uma crítica, mas simplesmente porque não consigo me conformar com a afirmação: “Prefira composição a herança” quando se deve usar herança no lugar de composição.
Té+