How does constructor inheritance work in Java?

1

In Java when one class inherits from another it is necessary to initialize the constructor of the parent class, right? using super() and passing to this super() the parameters that the parent constructor asks for.

Parent class example:

public class Pessoa{
    protected String nome;
    protected String dataNasc;

    public Pessoa(String a, String b){
        nome = a;
        dataNasc = b;
    }
}

Here the constructor asks for two strings , I want a heir class from this to have a constructor that receives as parameters String and int , so how do I initialize super() ?

This is the heir class:

public class Cliente extends Pessoa{

    protected String endereco;
    protected static int codigoCliente;


    public Cliente(String a, int b){
        endereco = a;
        codigoCliente = b;
    }

}

Her constructor asks for a String and an integer, doing this:

public Cliente(String a, int b){
    super(a, b);
    endereco = a;
    codigoCliente = b;
}

It gives error because I started with different types, my solution was this:

public Cliente(String a, Integer b){
    super(a, b.toString());
    endereco = a;
    codigoCliente = b;
}

Is there another way to initialize a constructor from an heir that has to have different parameters than the parent constructor?

    
asked by anonymous 02.01.2015 / 21:50

2 answers

8

This does not make sense. The Cliente constructor is receiving, according to you, an address and a client code. You are not getting a name and a date of birth. You can not get an address and play in the name, even if they are of the same type, nor a code and play on the date of birth. The compiler may not complain if the types are compatible, but that does not mean that it's right. He can not know the semantics you want to give the data.

Then it stands to reason that it is impossible for you to initialize a whole class if you do not have all the data. You have some alternatives depending on what you want.

The most obvious is to request all the required data in class Cliente :

public Cliente(int codigo, String nome, String endereco, Date dataNasc){
    super(nome, dataNasc);
    this.endereco = endereco;
    codigoCliente = codigo;
}

Note that if the class field name matches that of the parameter I can do disambiguation using this to show that it is the instance field of the class.

Note also that I preferred to receive the date of birth as a type Date , it makes more sense. It's obvious that you need to change the type in the Pessoa class as well.

I've put more meaningful names in the parameters. Learn to program for easy code understanding.

I changed the order of the parameters because it seems to make more sense.

But if you look further, you will see that the organization of these classes still makes less sense. If it is a client has a code but if it is another type of person do not have? This is strange to me. The same goes for the address. Does everyone have a date of birth?

Another change I would make is to call the field currently called codigoCliente only codigo . If it is in the Cliente class, it is obvious that it is the client code. The name is redundant.

It also does not make sense for data that is clearly an instance field of the class to be declared as static . Static fields serve for unique class values throughout the application, they will not be present in each instance, on each object, it will only be in the same class. It is shared by all objects in this class.

I did not even mention the encapsulation. This is a problem but it escapes the scope of the question.

Another possibility is to leave some data unfilled if this is possible within what you expect.

public Cliente(int codigo, String nome){
    super(nome, null);
    codigoCliente = codigo;
}

I do not advise doing this but it's a possibility. This way you left both the address with no value as the date of birth.

I would do so:

public class Pessoa {
    protected String nome;
    protected Date nascimento;

    public Pessoa(String nome, Date nascimento){
        this.nome = nome;
        this.nascimento = nascimento;
    }
}

public class Cliente extends Pessoa{
    protected String endereco;
    protected int codigo;

    public Cliente(int codigo String nome, String endereco, Date nascimento) {
        super(nome, nascimento);
        this.endereco = endereco;
        this.codigo = codigo;
    }
}

You do not have to do this, but I think this form is more elegant. Still not perfect, I did not want to change anything fundamental to what you're trying to do.

    
02.01.2015 / 22:15
7

Do not mix things up

You should not pass anything to the constructor of the parent class. This is not so much object-oriented.

If the parent class receives a nome and a dataNasc then the child class must receive those values in addition to the ones it already receives.

The correct implementation, both technically and in terms of values, would look like this:

public class Cliente extends Pessoa {

    protected String endereco;
    protected int codigoCliente;


    public Cliente(String a, String b, String c, int d) {
        super(a, b);
        endereco = c;
        codigoCliente = d;
    }

}

In short, your problem is not about types, but what values are needed.

Consider that the child classes is an extension of the parent class, so the attributes are cumulative.

Do not mess with what you do not understand

Remove static from attribute codigoCliente . This would make the value shared among all instances of the class.

Avoid confusion

Use more descriptive parameter names than a or b . Maybe that way you would not have been confused right from the start.

For example:

public class Pessoa {
    protected String nome;
    protected String dataNasc;

    public Pessoa(String nome, String dataNasc){
        this.nome = nome;
        this.dataNasc = dataNasc;
    }
}

And the class Cliente :

public class Cliente extends Pessoa{

    protected String endereco;
    protected int codigoCliente;


    public Cliente(String nome, String dataNasc, String endereco, int codigoCliente) {
        super(nome, dataNasc);
        this.endereco = endereco;
        this.codigoCliente = codigoCliente;
    }

}
    
02.01.2015 / 22:14