Inheritance, polymorphism and access to methods

Asked

Viewed 483 times

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 you to be able to create an instance equivalent to the enumerator applied to the type:

For example, if I was able to access the members (attributes, fields and methods) of the Personal class, I could access it, because it would call the correct constructor:

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

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

I modified Enum, implementing an abstract method that returns me 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 am creating the object as follows:

Pessoa p1 = TipoPessoa.PESSOAFISICA.obterPessoa();

When I ask him to print the type of the created object he tells me he created it correctly:

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

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

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

Diagrama de classes

  • 1

    can give an example, your question is not very clear

  • Hello, as in the image. I have a class Person who has as a daughter the Personal Physical class, each has its methods and attributes. I want the child class when I seal it from the parent class to still have visibility on its own attributes. What it shows in the picture is just this, I can not have visibility of any method of the Personal Physique class.

1 answer

5


I think you want to create a instance and not a resort.

I don’t like the term attribute, I prefer field.

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

If you can guarantee that the object is of the child type can make a cast, which is a type conversion (it doesn’t necessarily change something in the data, it just tells the compiler that it wants to use a more specialized type. There it is allowed to access the members of the type son, and of the father also because the son always has everything the father has.

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

In this example it doesn’t make much sense to declare p1 as Pessoa if you know you need it like PessoaFisica, but it is possible, then you can write:

((PessoaFisica)p1).cpf

I put in the Github for future reference.

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

It can also be done with reflection, but it is absurdly worse and unreasonable.

Just because a tool solves what you wanted doesn’t mean it’s right to use it.

Ferramenta errada para a tarefa - Cavalo dentro de um carro comum

  • Hi Maniero, all right? I corrected the text. The goal is that the generated instance behave as I specify at runtime. For example: I will register a person in a database. This person has the type attribute (Enum) that I can choose between Personal or Personal. This Enum returns a constructor according to the option. But I can’t access the child class attributes. I am trying to do this without using an interface: https://www.youtube.com/watch?v=rC296hM-S4g&t=1211s (This is a lesson on Strategy).

  • He was convinced that "field" was used by those who use C# and "attribute" for those who use java. In such a way that, in the answers I give, I have the concern to use one or the other according to the tag associated with the question.

  • 3

    @ramaral I was also, I was researching + and changed. There are those who do not agree or who do not give a shit. Sopt has been an inspiration to learn a lot in the right way. I’m not saying I’m getting it, but I’m trying. I need time to sort out everything I said about attribute. So I think we need a space to produce canonical knowledge more freely and creatively, without letting the mess take over. It is a pity that some people who contributed to this have disappeared or participate little. There are still some who help in this evolution, even questioning the errors :)

  • @Joséluizgonzaganeto I don’t know if a is a good strategy (with no intention of pun :) ), but with so little information I can’t say anything. At least it doesn’t seem that what you need in your example is a Strategy.

  • @Maniero, was taking a look, you are sure about the use of the term field, so much so that the language itself refers when we speak of reflection, for example: the getFields method(). I have never attempted this question before.

  • Through Reflection strategy I can access the fields and methods that are not available, but I did not find it practical in a class that has many fields.

  • @Joséluizgonzaganeto flees from the streets, the answer you posted and deleted is based on a very bad tip and not very good. I still don’t understand what you’re trying to do, but it doesn’t seem right. Try to use the tools as they were created to be used. If you really need to do it differently, and I doubt you do, don’t use the tool that limits you. If you access child type members, use child type. If you need to control the type of child in a type that depends on its existence then inheritance is not the correct mechanism. OOP is hard and learning wrong is worse than not using.

  • kkkk so I deleted, I will follow this way anyway. instantiate the daughter from the daughter.

  • 2

    That response was a recoil of useful information :)

  • Hi @Maniero, you are right, it is no use to keep inventing means that in front can generate some kind of damage and rework, I thank the sincerity.

  • 1

    "There are still some who help in this evolution, even questioning the errors" - Reviewers play a very important role in the process of "knowledge production" :)

Show 6 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.