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.
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.
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.
[quote=igor_ks]Complementando o que o drsmachado disse, para vc conseguir acessar portanto, vc precisa fazer o cast para PF
[/quote]
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:
[code]Pessoa p;
if(tipo == ‘F’){
p = new PF();
((PF)p).setCpf(“0000”);
} [/code][/quote]
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.