Duvida Básica de Herança

Olá Pessoas!
I’m back! 8)

Fiquei um periodo sem programar e acho que voltei um pouco enferrujada. :lol:

Criei uma classe Pessoa, onde pessoas podem casar-se e divorciar-se, com todas as restrições de idade, sexo, etado civil etc. Até aqui ok.

A seguir, me foi pedido estender a classe criada, para que a mesma modele os filhos resultantes de um casamento. Alem disso, devo implementar metodos como getAvo(), getTio(), getPrimo(), getMae(), getPai()… de uma determinada Pessoa.

Minha duvida eh sobre a melhor forma de fazer isso. Pensei em criar uma classe Filho, que estende Pessoa e possui os atributos adicionais pai e mae. E nela criar os metodos pedidos.
Mas nao deu muito certo, fiz uma confusao danada com os tipos Filho e Pessoa.

Por exemplo, o método terFilhos() deve estar na classe Pessoa ou na classe Filho? se getMae() deve retornar um objeto Pessoa (ai vou ter q sair fazendo casting…) ou um objeto Filho?

Ou será que seria melhor criar apenas a classe Pessoa, ja com os atributos pai e mae e um array de filho? Nesse caso, como eu poderia obter tios e primos?

Será que me fiz entender? hehehe

Sei que essa duvida eh bem basica, mas estou enferrujada mesmo… :oops:

Abraço a todos!!! :smiley:

Come on, people! :slight_smile:

Sou novo em java também, mas vou tentar dar uma ajuda. Não sei se vai resolver.

No seu caso, eu deixaria a classe Pessoa abstrata, para servir como modelo. Nela colocarias métodos e atributos que todo tipo de Pessoa irá ter, como Nome, Idade e etc. As classes que extendem de Pessoa como Filho, Mãe e Pai, acredito que deverão ter um atributo adicional para identificação dos mesmos. Quanto ao método casar() e terFilhos() eu criaria em outra classe, pois irá necessitar de 2 pessoas para o usa-los, não? Não sei se é bem isso, aieuhaeiue. Iniciante é foda
:smiley:

Olha, esses exemplos de facul são meio fora da realidade do que tu vai realmente usar. Mas ai vai…

eu criaria a classe Pessoa abstrata com o método abstrato casarCom(? extends Pessoa) e metodos para getPai(), getPrimo(), getMae(), etc. Depois criaria as classes Homem e Mulher extendendo pessoa. Na classe homem e mulher tu vai implementar o metodo casarCom(“Sexo oposto enquanto a lei nao permite casamento homossexual hehehehe”). Metodo terFilhos(int numeroFilhos) retornando Pessoa[] fica na classe Mulher.
Acho que nao precisa a classe Filho, pois filho sera Homem ou Mulher.

Hum… acho que você tem de derivar uma classe Homem e outra Mulher por causa da história de uma pessoa ter obrigatoriamente um pai e uma mãe. Comecei a fazer e acho que em vez de usar List é interessante usar Set, já que muitas coisas exigem não estarem repetidas. Comecei a esboçar alguma coisa abaixo.

enum Sexo {
    MASCULINO, FEMININO
}
class Pessoa {
    private Pessoa pai, mae; private Sexo sexo;
    // Usar "protected" faz com que eu não possa instanciar uma Pessoa, mas só um Homem ou uma Mulher. 
    protected Pessoa (Pessoa pai_, Pessoa mae_, Sexo sexo_) { pai = pai_; mae = mae_; sexo = sexo_;}
    private Set<Pessoa> filhos = new LinkedHashSet<Pessoa>();
    public boolean equals (Object obj) { ... }
    public int hashCode () { ... }
    public Set<Pessoa> getFilhos() { return filhos; }
    public Set<Pessoa> getPais() {
        Set<Pessoa> pais = new LinkedHashSet<Pessoa>();
        pais.add (pai); pais.add (mae);
        return pais;
    }
    public Set<Pessoa> getAvos() { 
        Set<Pessoa> avosPaternos = pai.getPais();
        Set<Pessoa> avosMaternos = mae.getPais();
        Set<Pessoa> avos = new LinkedHashSet<Pessoa>();
        avos.addAll (avosPaternos);
        avos.addAll (avosMaternos);
        return avos;
    }
    public Set<Pessoa> getIrmaos() {
        // Irmaos são os filhos de seus pais, exceto você
        Set<Pessoa> irmaosPai = pai.getFilhos();
        Set<Pessoa> irmaosMae = mae.getFilhos();
        Set<Pessoa> irm = new LinkedHashSet<Pessoa>();
        irm.addAll (irmaosPai); irm.addAll (irmaosMae);
        Set<Pessoa> irmaos = new HashSet<Pessoa>(irm);
        irmaos.remove (this);
        return irmaos;
    }
    public Set<Pessoa> getSobrinhos() {
        // Sobrinhos são os filhos de seus irmãos
    }
}
public Homem extends Pessoa {
    public Homem (Homem p, Pessoa m) { super (p, m, Sexo.MASCULINO); }
    public Pessoa terFilho (Mulher m) { 
        // Se não me engano, nascem mais homens que mulheres, mas também morrem mais homens que mulheres
        if (Math.random() <= 0.52) return new Homem (this, m); else return new Mulher (this, m); 
    }
}
public Mulher extends Pessoa {
    public Mulher (Pessoa p, Pessoa m) { super (p, m, Sexo.MASCULINO); }
    public Pessoa terFilho (Homem p) { 
        if (Math.random() <= 0.52) return new Homem (p, this); else return new Mulher (p.this); 
    }
}

Se entendi direito, acho que vc não tem que fazer quase nada…

Apenas construa a classe Pessoa e faça as associações dela para ela mesma que representa as relações que vc precisa, ou seja, em uma relação pai e filho vc inicia uma associação com role de filho e termina na própria classe com uma role pai e assim por diante. Fica esperta com as cardinalidades.

Para vc comprovar o seu modelo vc terá que montar um DIAGRAMA DE OBJETOS (não de classe) .

flws

Bom, na verdade, a definição de uma classe é mais relacionada ao conceito de definição da biologia, de definição de espécies. Você é filha do seu pai, mas ambos pertencem a mesma espécie e, portanto, a mesma classe.

No caso da herança genética a característica de dois indivíduos se misturam. Entretanto, em OO, o que define as características de um indíviduo é o valor de seus atributos, não que atributos eles possuem. Ou seja, a mistura de seu pai e sua mãe vão definir a cor dos seus olhos. Já sua classe, vai definir que você tem olhos e que esses olhos tem uma cor. Note a diferença aqui entre um valor de um atributo (o olho é verde) e a presença do atributo em si (ter um olho).

Por isso, ter uma relação Filho extends Pai, também não é uma boa estratégia de modelamento. O filho terá exatamente os mesmos atributos dos seus pais, sendo que a única coisa que mudará são os valores desses atributos (o filho pode ser loiro como a mãe e ter olhos verdes como os do pai, mas eles não terão nenhum atributo “a mais”, como antenas, para que tenham que ser colocados em outra espécie…).

E também foi por isso o Thingol optou para, se for para usar herança, dividir os serem humanos em duas “espécies” diferentes “homens” e “mulheres”. E esses sim, tem características diferentes (mulheres podem dar a luz aos filhos).

Será que não está aí a raiz da sua confusão?

[quote=fantomas]Se entendi direito, acho que vc não tem que fazer quase nada…

Apenas construa a classe Pessoa e faça as associações dela para ela mesma que representa as relações que vc precisa, ou seja, em uma relação pai e filho vc inicia uma associação com role de filho e termina na própria classe com uma role pai e assim por diante. Fica esperta com as cardinalidades.

Para vc comprovar o seu modelo vc terá que montar um DIAGRAMA DE OBJETOS (não de classe) .[/quote]
A sugestão do fantomas é interessante. No final das contas, você teria uma árvore genealógica, onde cada nó seria um objeto do tipo pessoa.

class Pessoa { Pessoa pai, mae; Set<Pessoa> filhos; }
Nesse modelo, o avô paterno seria o pai do pai:

pessoa.getPai().getPai();

O tio paterno seria o irmão do pai:

pessoa.getPai().getPai().getFilho("Nome do tio");

E assim vai…