Parent class array with two different subclasses

Asked

Viewed 485 times

0

I created a program for the following exercise:

Exercise: Do a program to register customers from an accountant’s company. It is important to store customer information such as name, address, phone number and email.

In addition, it should be noted that the accountant meets both individuals and legal entities, which differ by the fact that the first has CPF and the second has a CNPJ. The program must register customers indefinitely until the user no longer wishes.

At the time of registration, the program should ask the user what type of client wants to register, after that the program should display a report with all registered clients as follows:

type: physics
name:
Cpf:

The code is as follows:

public class Cliente{
    private String nome;
    private String endereco;
    private String telefone;
    private String email;

    public Cliente(String nome, String endereco, String telefone, String email){
        this.nome=nome;
        this.endereco=endereco;
        this.telefone=telefone;
        this.email=email;
    }

    public String getNome(){
        return nome;
    }
    public String getEndereco(){
        return endereco;
    }
    public String getTelefone(){
        return telefone;
    }
    public String getEmail(){
        return email;
    }
}

public class PessoaFisica extends Cliente{
    private String cpf;

    public PessoaFisica(String nome, String endereco, String telefone, String email, String cpf){
        super(nome, endereco, telefone, email);
        this.cpf=cpf;
    }
    public String getCpf(){
        return cpf;
    }
    public String toString(){
        return "tipo: fisica";
    }
}

public class PessoaJuridica extends Cliente{
    private String cnpj;

    public PessoaJuridica(String nome, String endereco, String telefone, String email, String cnpj){
        super(nome, endereco, telefone, email);
        this.cnpj=cnpj;
    }
    public String getCnpj(){
        return cnpj;
    }
    public String toString(){
        return "tipo: juridica";
    }
}

import java.util.*;

public class MainContador{
    public static void main(String args[]){
        int op=1;
        int tipo;
        List<Cliente> listaClientes = new ArrayList<>();
        Scanner dado = new Scanner(System.in);
        do{
            System.out.println("Opcoes de cadastro:\n(1)pessoa fisica.\n(2)pessoa juridica");
            tipo = dado.nextInt();
            dado = new Scanner(System.in);

            if(tipo==1){
                System.out.println("Nome:");
                String nome = dado.nextLine();
                dado = new Scanner(System.in);

                System.out.println("Endereco:");
                String endereco = dado.nextLine();
                dado = new Scanner(System.in);

                System.out.println("Telefone:");
                String telefone = dado.nextLine();
                dado = new Scanner(System.in);  

                System.out.println("Email:");
                String email = dado.nextLine();
                dado = new Scanner(System.in);

                System.out.println("Cpf:");
                String cpf = dado.nextLine();
                dado = new Scanner(System.in);  

                PessoaFisica pf = new PessoaFisica(nome, endereco, telefone, email, cpf);

                listaClientes.add(pf);  
            }
            else if(tipo==2){
                System.out.println("Nome:");
                String nome = dado.nextLine();
                dado = new Scanner(System.in);

                System.out.println("Endereco:");
                String endereco = dado.nextLine();
                dado = new Scanner(System.in);

                System.out.println("Telefone:");
                String telefone = dado.nextLine();
                dado = new Scanner(System.in);  

                System.out.println("Email:");
                String email = dado.nextLine();
                dado = new Scanner(System.in);

                System.out.println("Cnpj:");
                String cnpj = dado.nextLine();
                dado = new Scanner(System.in);  

                PessoaJuridica pj = new PessoaJuridica(nome, endereco, telefone, email, cnpj);

                listaClientes.add(pj);  
            }

            System.out.println("Para cadastrar outro cliente, digite 1, para sair digite outro numero qualquer.");
            op = dado.nextInt();
            dado = new Scanner(System.in);
        }while(op==1);

        for(int i=0; i<listaClientes.size(); i++){
            Cliente c = listaClientes.get(i);

            if(c.toString()=="tipo: física"){
                System.out.println(c.toString());
                System.out.println("\nNome:" + c.getNome());
                System.out.println("\nEndereco:" + c.getEndereco());
                System.out.println("\nTelefone:"+c.getTelefone());
                System.out.println("\nEmail:"+c.getEmail());
                //System.out.println("\nCPF:"+c.getCpf());
                System.out.println("\n___________________\n");
            }
            else{
                System.out.println(c.toString());
                System.out.println("\nNome:" + c.getNome());
                System.out.println("\nEndereco:" + c.getEndereco());
                System.out.println("\nTelefone:"+c.getTelefone());
                System.out.println("\nEmail:"+c.getEmail());
                //System.out.println("\nCNPJ:"+c.getCnpj());
                System.out.println("\n___________________\n");
            }
        }
    }
}

Commenting on the lines of c.getCnpj() and c.getCpf() the program runs normally, but then I cannot display these values of my object. The question is, when compiling, the method is not found in the objects. Why the method getString() is found and the getCpf() or getCnpj() No? What’s the problem?

  • 1

    Did any of the answers solve your question? Do you think you can accept one of them? Check out the [tour] how to do this, if you haven’t already. You would help the community by identifying what was the best solution for you. You can accept only one of them. But you can vote on any question or answer you find useful on the entire site (when you have enough score).

2 answers

4

There’s a lot of conceptual errors there, and that’s why it causes the problem. Almost everyone makes the conceptual mistake they’ve made, some even insist it’s right, and if you’re going to present it to someone to evaluate it might be that whatever they want. And the error you got already shows how wrong this is. If it were modeled the right way would not have this error.

There’s a detail that caught my attention, the statement doesn’t say inheritance, it doesn’t say anything that needs to have separate classes for each thing, why did it?

People shouldn’t inherit from customers because being a client is a role of a person and not a person, just as people can be other things than a client, so this doesn’t make sense. Either you create people and compose them with the role of client, or you use the role of client and associate with a natural or legal person. Or create a class Cliente which is what the statement asks for and only, whether it is physical or legal in there. Everything suggests that the purpose of the exercise is this, and if it is not it is poorly formulated. How Cliente is a role it should not have name, address, etc., who has these things are persons, physical or legal. But as the statement says to be so he’s probably treating the client as a person, so there’s no point in creating the person in isolation.

If you do this the problem ceases to exist, because it is a problem caused by wrong modeling, fixing it is legitimizing the problem.

To explain to you what happens, is that in your client list you have both people, then some objects have the CPF, other have the CNPJ, you can not access CPF in PessoaJuridica and cannot access the CNPJ in PessoaFisica, as the error indicates, simply because the object does not have it.

To access the method you want the object has to be the type you are waiting for. Then you would have to do a cast to transform the Cliente who doesn’t have the method he wants in one of the two people he has:

System.out.println("\nCPF:" + ((PessoaFisica)c).getCpf());

And

System.out.println("\nCPF:" + ((PessoaJuridica)c).getCnpj());

But there’s another mistake. This toString() is conceptually wrong, this method was not created for this, it is gambiarra and one of the worst forms of use of it I have ever seen. This method is to show a very simple form, that is, without formatting, something that identifies the object, so the pattern is up to the address of the object, thus giving a unique identity. Its use besides presenting a formatted data, which is not the purpose of it, also loses identity, different objects are printed with the same information. Solved your problem but threw away the functionality of this method.

Fiat 147 todo detonado andando pelas ruas

Should have a given in Cliente which unequivocally defines what kind of person he is and which can be picked up with specific semantics for this, which only the Cliente knows what it is, not something that any Object you know this is the case with toString().

Note that you do not have a method called getString(). The toString() exists throughout Object, and every object derives from Object, then they all have this method.

There, since you will have a field (and possibly getters, here I won’t even discuss if I should use this) to define the person’s type, why not have a field with that client’s document number? And it can be one field only. But it could have two if it feels very important, in the exercise it says nothing about it.

But if you insist on keeping these classes don’t use the toString() that way, just do this:

if (c instanceof PessoaFisica) {

I put in the Github for future reference.

My suggestion is to make the code conceptually right, this would simplify it enormously and solve the problem alone. I would take advantage and eliminate the duplications in it.

1

Your code has several problems and improvements that can be made, but in short, the answer to your question is: Why are you saying that c is an instance of Cliente and this class doesn’t have the methods getCpf and getCnpj. To use these methods you need to specify which class you use, for example:

System.out.println("\nCPF:" + ((PessoaFisica ) c).getCpf());

Browser other questions tagged

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