Inheritance, polymorphism and access to methods

0

I have 3 classes and 1 enum :

public class Pessoa {
        private TipoPessoa tipo;
        public TipoPessoa getTipo() {
            return tipo;
        }
        public void setTipo(TipoPessoa tipo) {
            this.tipo = tipo;
        }
      }



public class PessoaF  extends Pessoa{
                private String cpf;
                public String getCpf() {
                    return cpf;
                }
            public void setCpf(String cpf) {
                this.cpf = cpf;
            }
         }



public class PessoaJ extends Pessoa{
            private String cnpj;
            public String getCnpj() {
                return cnpj;
            }
            public void setCnpj(String cnpj) {
                this.cnpj = cnpj;
            }
        }



public enum TipoPessoa {
            PESSOAFISICA, PESSOAJURIDICA;
        }

I want that when setting a type of person, can create an equivalent instance to the enumerator applied in type:

For example, if the sector is a PERSONAL PHYSICIAN, I could access the members (attributes, fields and methods) of the PersonF class, as it would call the correct constructor:

Pessoa p1 = new PessoaF();
p1.setCpf = 32443265332;

But with inheritance I can not access the members of a child class through an instance created from a parent class. So how to proceed?

I changed the enum, implementing an abstract method that returns the constructor I want to use according to the type of person set:

public enum TipoPessoa {
    PESSOAFISICA (0, "Pessoa Fisica") {
        @Override
        public Pessoa obterPessoa() {
            return new PessoaF();
        }
    },
    PESSOAJURIDICA (1, "Pessoa Juridica") {
        @Override
        public Pessoa obterPessoa() {
            return new PessoaJ();
        }
    };



    public abstract Pessoa obterPessoa();


    private TipoPessoa(){}
    private TipoPessoa(Integer cod, String desc) {
        this.cod = cod;
        this.desc = desc;
    }

    private Integer cod;
    private String desc;
    public Integer getCod() {
        return cod;
    }
    public void setCod(Integer cod) {
        this.cod = cod;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
 }

With this modification I'm creating the object as follows:

Pessoa p1 = TipoPessoa.PESSOAFISICA.obterPessoa();

When I request that it print the type of the created object it tells me that it has been created correctly:

 System.out.println(p1.getClass());
 Retorno : class Pessoas.PessoaF

But I still can not access the setCpf() method that is within the PessoaF class.

I want to create a person and according to the value set in the type attribute. And that this object created be able to access the members according to the option of the selected enumerator. How to proceed?

    
asked by anonymous 25.03.2018 / 19:57

1 answer

5

I think you want to create a instance rather than an estance .

I do not like the term attribute, I prefer field .

You can access all public members of the object type at that time. You can not access members of a type that is part of that object, but that is not the type being used at that time. If the type is the parent, it can only access its members, it can not access the child type members.

If you can guarantee that the object is of type child can do a cast , which is a type conversion (does not necessarily change anything in the given data, only tells the compiler that you want to use a type more specialized, allowing access to members of the child type, and the parent also because the child always has everything that the father has.

In general if cast fails it will generate an error or the result will be a null. There are cases where the compiler can identify that it is not possible or even compile.

In this example, it does not make much sense to declare p1 as Pessoa if you know that you need it as PessoaFisica , but you can write it here:

((PessoaFisica)p1).cpf

Performance will be worse if there is no optimization that the compiler is prepared to do.

It is also possible to do with reflection, but it is absurdly worse and unreasonable.

Just because a tool solves what you want does not mean it's right to use it.

    
25.03.2018 / 20:13