Dúvida sobre polimorfismo

8 respostas
Z

Pessoal, boa tarde.

Uma dúvida:

Tenho uma classe Pessoa abstrata e as suas filhas PF e PJ, cada uma com suas particularidades (cnpj, cpf…)

Não consigo acessar os métodos da PF por exemplo quando faço o seguinte:

Pessoa p;

if(tipo == 'F'){

p = new PF();

p.setCpf("0000"); // Não consigo visualizar

} else if(tipo == 'J'){

p = new PJ();

p.setCnpj("000"); // Não consigo visualizar

}

O que está de errado neste código?

Lembrando que estes métodos setCPF e setCNPJ são implementados apenas nas pessoas PF e PJ.

[]'s!

8 Respostas

Kevin_Stortz1

Cara,

Você não consegue visualizar pois a sua variável P está declarada como Pessoa, você não postou o código de Pessoa, mas pelo que pude entender, seria o certo, o atributo CPF está dentro de PF e CNPJ dentro de PJ, assim quando você declara como Pessoa você consegue apenas visualizar os atributos e métodos que estão dentro desta classe.

Se você quiser visualizar o CPF ou o CNPJ, nesta sua implementação, deverá declarar a variável P como PessoaFisica ou PessoaJuridica para ter o acesso respectivamente.

drsmachado

Considere:

public abstract class Pessoa {
    public abstract voud informaDadosPessoa();
}

E

public class PessoaFisica extends Pessoa {
    private String nome;
    private String cpf;

    @Override
    public void informaDadosPessoa() {
        System.out.println("Nome: " + nome + "\n" +
        "CPF: " + cpf);
    }
    //getters e setters
}

E:

public class PessoaJuridica extends Pessoa {
    private String razaoSocial;
    private String cnpj;

    @Override
    public void informaDadosPessoa() {
        System.out.println("Razão Social: " + razaoSocial + "\n" +
        "CNPJ: " + cnpj);
    }
    //getters e setters
}

Quando você faz:

Pessoa p = new PessoaFisica();

Está simplesmente dizendo que quer um objeto do tipo Pessoa (ou seja, que não possui nada em particular, além do método informaDadosPessoa). Isso implica em não conhecer nenhum detalhe sobre as especializações (as classes PessoaFisica e PessoaJuridica são filhas de Pessoa, logo, são especializações da mesma).
Qual a vantagem nisso? Bom, lembre-se que a herança é uma relação forte entre duas classes e que ela é extremamente engessante. Sendo assim, quando você faz uma extensão, tem de entender que está fechando as possibilidades.
Claro que é útil, por exemplo, se você tem um método e não sabe se receberá uma PF ou PJ, apenas aguarde uma Pessoa. Se você tem a possibilidade de ter vários tipos de pessoas diferentes, use um vetor de Pessoa. E assim por diante.

igor_ks

Complementando o que o drsmachado disse, para vc conseguir acessar portanto, vc precisa fazer o cast para PF

Z

Obrigado pessoal,

Agora ficou esclarecido.

drsmachado

igor_ks:
Complementando o que o drsmachado disse, para vc conseguir acessar portanto, vc precisa fazer o cast para PF

Apenas o cast talvez não seja suficiente. Talvez seja preciso instanciar o objeto como sendo da classe mais especialista, PJ ou PF.

igor_ks
drsmachado:
Apenas o cast talvez não seja suficiente. Talvez seja preciso instanciar o objeto como sendo da classe mais especialista, PJ ou PF.

Como ele está fazendo uma verificacao se é pessoa física antes, então nao vejo problema fazer o cast e nem vejo como gambiarra também.

Aí no caso ficaria assim:

Pessoa p;  
  
if(tipo == 'F'){  
  
p = new PF();  
  
((PF)p).setCpf("0000"); 
  
}
drsmachado
igor_ks:
drsmachado:
Apenas o cast talvez não seja suficiente. Talvez seja preciso instanciar o objeto como sendo da classe mais especialista, PJ ou PF.

Como ele está fazendo uma verificacao se é pessoa física antes, então nao vejo problema fazer o cast e nem vejo como gambiarra também.

Aí no caso ficaria assim:

Pessoa p;  
  
if(tipo == 'F'){  
  
p = new PF();  
  
((PF)p).setCpf("0000"); 
  
}
Eu entendo teu ponto de vista, porém, vejo isso
((PF)p).setCpf("0000");
Como poluição. Se ele verifica se é PF, então já instancie como PF, mesmo que seja necessário criar dois métodos distintos, um para PF outro para PJ, para preencher o objeto.
ViniGodoy

Geralmente, fazer um teste com “instanceof” já é um sinal de alerta, e de que código que pode ser refatorado.

Criado 6 de março de 2014
Ultima resposta 7 de mar. de 2014
Respostas 8
Participantes 5