[Resolvido] Pegar um metodo da subclasse

Como eu faço pra chamar o metodo de uma subclasse?
Tipo, eu tenho um arrayList e nele eu pego os metodos da classe pessoa, mas eu preciso pegar os métodos da subclasse Mulher pra utilizar na mesma arrayList.
Como faço isso?

Você não pode fazer isso.

Em herança o acesso é sempre de baixo para cima, ou seja você pode acessar um metodo de uma classe pai (desde que ele seja public ou protected) mas a a classe pai não tem acesso aos métodos da classe filho, na verdade a classe pai nem sabe que tem um(ns) filho(s).
O que você pode fazer é chamar um metodo abstrato da classe pai e implementa-lo na classe filha.

Não dá.
O que vc pode fazer é verificar se a instância em questão é do tipo necessário, fazer o cast e chamar o método desejado.

for ( Pessoa p : seuArrayList ) { if ( p instanceof Mulher ) { ( ( Mulher ) p ).metodoDesejadoDaClasseMulher(); } }

[]'s

1 curtida

david, não era exatamente isso mas valeu.
xandy, eu criei o metodo abstrato em Pessoa e implementei em Homem e Mulher, a classe Pessoa virou abstrata.
eu tenho uma terceira classe, é no main dela que eu inicializo tudo, é nela que eu crio as pessoas setNome()… e é nela que eu tenho que criar o peso e idade setPeso()… que estão na classe filha.
isso é um exercicio então eu tenho que manter esses metodos nessas classes entende?
eu to confusa, mas tenho que aprender hahahaha

[quote=andreacerqueira]david, não era exatamente isso mas valeu.
xandy, eu criei o metodo abstrato em Pessoa e implementei em Homem e Mulher, a classe Pessoa virou abstrata.
eu tenho uma terceira classe, é no main dela que eu inicializo tudo, é nela que eu crio as pessoas setNome()… e é nela que eu tenho que criar o peso e idade setPeso()… que estão na classe filha.
isso é um exercicio então eu tenho que manter esses metodos nessas classes entende?
eu to confusa, mas tenho que aprender hahahaha[/quote]

Agora quem ficou confuso fui eu, seja mais claro. Qual a sua duvida afinal?

eu quero cria o peso da pessoa só que o metodo de peso está nas classes filhas, a classe pai tem o metodo abstrato e a filha extende ele.
só que o main que estou usando pra criar essas pessoas está em outra classe.
vou colocar aqui de forma reduzida pra vc entender…

public class Arvore extends Pessoa {
    public static List<Pessoa> pessoas = new ArrayList<Pessoa>();

    public static void main(String[] args) {

	// criação de pessoas
	Arvore andrea = new Arvore();
	pessoas.add(andrea);
	andrea.setNome("Andrea Cerqueira");
	andrea.pesoAbs(56);
        ...
    }
}


public abstract class Pessoa {	
    protected String nome;
    protected List<Pessoa> exconj = new ArrayList<Pessoa>();
	
    public abstract void pesoAbs(double valor);
    ...
}

public class Mulher extends Pessoa {
    static double peso;
    static double altura;
    
    public void pesoAbs(double valor) {
        
    }

    public static void setPeso(double peso) {
        Mulher.peso = peso;
    }
    ...
}

Vê se vc consegue captar…

não sei bem se entendi qual é a sua duvida, mas se estou certo você está querendo criar na classe pessoa um método que será utilizado tanto na classe homem quanto mulher, ou seja independente do sexo a forma como será modificado o peso será a mesma. se realmente for isto você fará da seguinte forma.

public abstract class Pessoa {    
    protected String nome;  
    //você cria em pessoa um atributo peso
    // como em baixo tem o método pesoAbs este atributo pode ser privado
    private double peso;
    protected List<Pessoa> exconj = new ArrayList<Pessoa>();  
      
    /* e em pessoa você faz a implementação do metodo
     *como homem e mulher vão estender de pessoa automaticamente
     *irão receber o método implementado em pessoa
     *
     *uma classe por ser abstrata não significa que ela deve conter somente
     *métodos abstratos
    */
    public void pesoAbs(double valor){
    
    }  
    ...  
}  

qualquer coisa estou por aqui…

não, só mulheres terão peso, não me pergunte pq, é o exercicio :slight_smile:
dessa forma os setters e getters e o atributo peso estão na classe mulher.
mas estou criando as pessoas na classe arvore entendeu?

public class Arvore extends Pessoa {
    public static List<Pessoa> pessoas = new ArrayList<Pessoa>();

    public static void main(String[] args) {

	// criação de pessoas
	Arvore andrea = new Arvore();
	pessoas.add(p1);
	p1.setNome("Andrea Cerqueira");
	p1.pesoAbs(56);
        ...
    }
}

Porque a classe Arvore extende a classe Pessoa? O que arvore tem haver com pessoa? Você já entendeu o conceito de herança?

sim entendi.
a classe árvore é a classe de teste, ela existe pq é obrigatória no exercício :slight_smile:

Podes simplesmente criar uma mulher e adicionar à árvore.

como? não entendi.

eu crio a mulher, mas como adiciono ela a árvore???

[code]Arvore andrea = new Arvore();
pessoas.add(andrea);
andrea.setNome(“Andrea Cerqueira”);

Mulher andrea2 = new Mulher();
pessoas.add(andrea2);[/code]

isso cria outro nó na array list né? andrea2 não estaria na mesma row de andrea, seriam dados diferentes.
como faço isso pmlm?

Ué, e porque o que o David falou não serve?

Pessoa p = pessoas.get(10); if (p instanceOf Mulher) { Mulher mulher = (Mulher)p; mulher.setPeso(10); }

[quote=ViniGodoy]Ué, e porque o que o David falou não serve?

Pessoa p = pessoas.get(10); if (p instanceOf Mulher) { Mulher mulher = (Mulher)p; mulher.setPeso(10); }[/quote]

não entendi como isso iria setar o peso de mulher na minha arrayList

eu crio a mulher, mas como adiciono ela a árvore???

[code]Arvore andrea = new Arvore();
pessoas.add(andrea);
andrea.setNome(“Andrea Cerqueira”);

Mulher andrea2 = new Mulher();
pessoas.add(andrea2);[/code]

isso cria outro nó na array list né? andrea2 não estaria na mesma row de andrea, seriam dados diferentes.
como faço isso pmlm?
[/quote]

Mulher andrea = new Mulher();
andrea.setNome("Andrea Cerqueira"); 
andrea.setPeso(10);
pessoas.add(andrea);

eu crio a mulher, mas como adiciono ela a árvore???

[code]Arvore andrea = new Arvore();
pessoas.add(andrea);
andrea.setNome(“Andrea Cerqueira”);

Mulher andrea2 = new Mulher();
pessoas.add(andrea2);[/code]

isso cria outro nó na array list né? andrea2 não estaria na mesma row de andrea, seriam dados diferentes.
como faço isso pmlm?
[/quote]

Mulher andrea = new Mulher(); andrea.setNome("Andrea Cerqueira"); andrea.setPeso(10); pessoas.add(andrea); [/quote]

pqp desculpa a palavra mas só falando assim… era isso mesmo a coisa mais idiota do mundo hehehehe
agora tenhio que usar o getClass ou instanceOf como disseram por aqui pra descobrir de que classe vem e assim saber se é homem ou mulher.
muito, muito, muito obrigado.

ok já consigo diferenciar mulher de homem usando o getClass.
só que quando eu dou um loop pra pegar o peso, não funciona, pq o loop pega a lista de pessoas e homens são pessoas apesar de não ter peso, dessa forma o java não me deixar acessar o pessoas.peso da minha arrayList.
tipo:

for (int i = 0; i < pessoas.size(); i++) { //if ( pessoas instanceof Mulher ) { if (pessoas.get(i).getClass().getName() == "Mulher") { System.out.println(pessoas.get(i).peso); //aqui dá erro só dá acesso aos atributos da classe mãe. } }

Acho que você não entendeu ainda alguns conceitos de herança, vou explicar para você abaixo:

A classe Arvore NÃO DEVE extender de Pessoa!
Uma classe extende outra para adicionar novas responsabilidades. A classe mulher extende Pessoa por que uma Mulher é, antes de tudo, uma Pessoa! A classe mulher adiciona novas responsabilidades a classe pessoa, mas não descaracteriza o objeto Pessoa . Agora eu não posso dizer que uma Arvore é uma Pessoa né!

Porém a classe é Arvore pode conter uma referencia a uma classe Pessoa. Eu posso dizer que uma arvore contém uma pessoa, mas não posso dizer que uma Arvore é uma pessoa.
Pessoa e Arvores contém caracteristicas extremamente distintas!

É fundamental que você entenda a diferença entre TEM UM e É UM. Se você não entender isso vai criar uma salada de frutas!

Pelo que você falou a classe homem não contem dados referentes ao peso, somente a classe mulher, então não faz sentido colocar esse método na classe pessoa, mesmo sendo abstrato! Pois esse método somente é implementado na classe mulher!
Porém fica uma pergunta existe uma pessoa que não é um Homem ou uma Mulher? Eu acretido que não, até porque isso não faz muito sentido. Existe homem e existe mulher, mas não pode existir uma pessoa sem sexo, nesse caso! Dissemos então que a classe pessoa é uma generalização da classe homem e da classe mulher. Fazemos isso por que ambos tem caracteristicas em comum e não queremos replica-las. Porém não pode existir um objeto pessoa, pois isso não faria sentido! Como eu posso ter uma pessoa sem sexo né? Então essa classe pessoa deve ser abstrata (mesmo não contendo nenhum método abstrato).

ATENÇÃO: ISSO É UM EXEMPLO, VOCÊ PODE TER EM ALGUM LUGAR UMA CLASSE CONCRETA PESSOA, ESTOU UTILZANDO ISSO PARA EXEMPLIFICAR O USO DE UMA CLASSE ABSTRATA.

Codificando você acabaria tendo algo assim:

public abstract Pessoa()
    private String nome;
    private int idade;

    public String getNome(){    
        return nome;
    }

    public void setNome(String nome){
        this.nome = nome;
    }

    public int getIdade(){
        return idade;
    }

    public void setIdade(int idade){
        this.idade = idade;
    }
}

Como a classe pessoa é abstrata você não pode fazer isso:

public Teste() public static void main(String[] args){ Pessoa novaPessoa = new Pessoa; } }
Pois não vai nem compilar! E é isso que você quer pois uma pessoa não existe se ela não for um homem ou uma mulher então você faz isso:

[code]public Mulher extends Pessoa()
private Double peso;

public Double getPeso(){    
    return peso;
}

public void setNome(Double peso){
    this.peso = peso;
}

}

public Homem extends Pessoa()
private booelan barrigaDeCerveja;

public booelan getBarrigaDeCerveja(){    
    return barrigaDeCerveja;
}

public void setBarrigaDeCerveja(boolean valor){
    barrigaDeCerveja = valor;
}

}
[/code]
Bom agora você tem 3 classes! Uma classe pessoa que é abstrata pois não pode existir sem que seja implementada por outra classe e uma classe mulher que tem um caracteristica específica que o peso e um classe homem que tem uma caracteristica especifica que a barriga de cerveja.
Dizemos que a classe pessoa é uma generalização das classes homem e mulher e que a classe homem e mulher é uma especialização dessas outras classes.

Bom até ai tudo bem, mas seu professor, quer que você armazene todas as pessoas de um determinado lugar. Bom como você é experta faz o seguinte:s

[code]public ArmazenaPessoas()
private List homens = new ArrayList();
private List mulheres = new ArrayList();

public void carregarPessoas(){
    Homen novoHomem = new Homem();
    novoHomem.setNome(Alexandre);
    novoHomem.setIdade(33);
    novoHomem.setBarrigaDeCerveja(false);
    homens.add(novoHomem);
   
    Mulher novaMulher = new Mulher();
    novaMulher.setNome("Andrea");
    novaMulher.setIdade(23);
    novaMulher.setPesso(60.00);
    mulheres.add(novaMulher);
}

public static void main(String[] args){
     ArmazenaPessoas armazem = new ArmazenaPessoas();
     armazem.carregarPessoas();
} 

}[/code]
Bom isso está correto! Assim você pode armazenar todas as pessoas que seu professor mandou. Mas ai seu professor diz, Andrea eu quero que você disponibilize um método no qual eu informe o nome de uma pessoa e ele me devolva essa pessoa, não quero saber se é homem ou se é mulher eu quero somente receber um objeto pessoa para imprimir seus dados!

Você pensa então, “nossa como faço isso”?

Para fazer isso existe uma propriedade da OO, que permite a atribuição de um objeto mais especializado a um objeto mais geral!, deste que esse objeto tenham um relacionamento de herança. Isso quer dizer que você pode atribuir a uma Pessoa um objeto Homem ou um objeto Mulher. O objeto pessoa só tem acesso aos metodos que foram implementados nele, no caso o nome e a idade, o objeto pessoa não tem acesso aos metodos que foram implementados nos seus filhos, na verdade ele nem sabe que tem filhos, é um pai desnaturado. Por isso que você não pode chamar a partir do pai um método implementado no filho, por exemplo, o peso da mulher.
Observação: O relacionamento não necessita ser direto, tipo pai->filho, pode ser pai->filho->neto, onde pai = neto, ou seja o eu atribuo o neto ao pai.

Implementando, você ficaria com algo assim:

[code]public ArmazenaPessoas()
private List homens = new ArrayList();
private List mulheres = new ArrayList();

public void carregarPessoas(){
    Homen novoHomem = new Homem();
    novoHomem.setNome(Alexandre);
    novoHomem.setIdade(33);
    novoHomem.setBarrigaDeCerveja(false);
    homens.add(novoHomem);
   
    Mulher novaMulher = new Mulher();
    novaMulher.setNome("Andrea");
    novaMulher.setIdade(23);
    novaMulher.setPesso(60.00);
    mulheres.add(novaMulher);
}
public Pessoa localizarPessoa(string nome){
    for(Mulher mulher : mulheres) //não se preocupa se não entender esse código, é um laço diferente do java
       if (mulher.getNome().equal(nome)) //Caso encontre uma mulher com o nome informado retorna a mulher
           return mulher;

    for(Homem homem : homems) //não se preocupa se não entender esse código, é um laço diferente do java
       if (homem.getNome().equal(nome)) //Caso encontre um homem com o nome informado retorna esse homem
           return homem;

    return null; // Não encontrou nem um homem nem uma mulher.
}

public static void main(String[] args){
     ArmazenaPessoas armazem = new ArmazenaPessoas();
     armazem.carregarPessoas();
     Pessoa pessoa = armazem.localizarPessoa("alexandre"):
     if (pessoa != null)
         System.out.println("Nome: " + pessoa.getNome() + " - Idade: " + pessoa.getIdade());
} 

}[/code]
Esse código está bom mas com o conhecimento que adquirimos podemos refatora-lo, pois o que foi pedido é que fosse um armazenados pessoas e não homens e mulheres então podemos fazer isso:

[code]public ArmazenaPessoas()
private List pessoas = new ArrayList();

public void carregarPessoas(){
    Homen novoHomem = new Homem();
    novoHomem.setNome(Alexandre);
    novoHomem.setIdade(33);
    novoHomem.setBarrigaDeCerveja(false);
           
    Mulher novaMulher = new Mulher();
    novaMulher.setNome("Andrea");
    novaMulher.setIdade(23);
    novaMulher.setPesso(60.00);
    
     pessoas.add(novoHomem);
     pessoas.add(novaMulher);
}
public Pessoa localizarPessoa(string nome){
    for(Pessoa pessoa : pessoas) //não se preocupa se não entender esse código, é um laço diferente do java
       if (pessoar.getNome().equal(nome)) //Caso encontre uma pessoa com o nome informado retorna essa pessoa
           return mulher;

    return null; // Não encontrou nenhuma pessoa com o nome!
}

public static void main(String[] args){
     ArmazenaPessoas armazem = new ArmazenaPessoas();
     armazem.carregarPessoas();
     Pessoa pessoa = armazem.localizarPessoa("andrea"):
     if (pessoa != null)
         System.out.println("Nome: " + pessoa.getNome() + " - Idade: " + pessoa.getIdade());
} 

}[/code]Você pensou que terminou, mas seu professor muda de ideia. Agora ele quer você faça uma busca por pessoa imprima seus dados e se essa pessoa for uma mulher imprima seu peso.

Mas como você pode fazer isso se a partir se a classe pessoa não pode acessar seus filhos? Você até pensa em declarar o método peso na classe pessoa como abstrato, mas ai você ve que isso é somente uma caracteristica da mulher e se fizer isso vai ter que implementar no homem também e você não quer fazer isso né, pois está atribuindo a ele uma característica que não é dele.

Mas tem um jeito de resolver isso. Já foi dito que você pode atribuir a uma classe mais geral uma classe mais especifica, desde que elas tenham um relacionamento de herança.
O que não foi dito é que esse objeto mais geral guarda é uma referencia ao objeto mais especifico, ou seja o que ele tem dentro dele é outro. Por fora ele é João, mas por dentro ele é Maria. Esse objeto se faz de machão, so mostrando seus atributos e esconde a sua parte Maria, mas ela ta la dentro só temos que saber como fazer para ele se mostrar.

Para fazer isso temos que fazer uma conversão de tipos (Type Cast), usando parte do código acima temos isso.

public ArmazenaPessoas() public static void main(String[] args){ ArmazenaPessoas armazem = new ArmazenaPessoas(); armazem.carregarPessoas(); Pessoa pessoa = armazem.localizarPessoa("andrea"): if (pessoa != null){ System.out.println("Nome: " + pessoa.getNome() + " - Idade: " + pessoa.getIdade()); //Retirando a maria do joão.... Mulher maria = (Mulher)pessoa;// A parte entre parentes é especifica diz que aquilo é uma mulher e não somente uma pessoa. System.out.println("Peso: " + maria.getPeso()); } } }
Só que ai surge um problema e se o objeto pessoa for um Homem mesmo e não uma Mulher? Ao tentar converter você terá uma bela de uma exceção, dizendo aqui é o “João, não tem nada de Maria aqui não, sai fora…”
Para evitar isso você deve verificar se o João realmente tem uma Maria dentro dele e você faz isso assim

public ArmazenaPessoas() public static void main(String[] args){ ArmazenaPessoas armazem = new ArmazenaPessoas(); armazem.carregarPessoas(); Pessoa pessoa = armazem.localizarPessoa("andrea"): if (pessoa != null){ System.out.println("Nome: " + pessoa.getNome() + " - Idade: " + pessoa.getIdade()); //Verifica se realmente é uma mulher, ou seja se o joão realmente tem uma maria dentro dele if(pessoa instanceof Mulher){ //Retirando a maria do joão.... Mulher maria = (Mulher)pessoa;// A parte entre parentes é especifica diz que aquilo é uma mulher e não somente uma pessoa. System.out.println("Peso: " + maria.getPeso()); } } } }

Bom esse é um resumão, espero que te ajude a enteder. Abraços

1 curtida

Nossa senhora :slight_smile:
Muitissimo obrigado.
Agora vou demorar a responder pois até ver tudo…
Mas valeu mesmo pela explicação completa.