How do I access getters and sub-class setters?

Asked

Viewed 140 times

6

In this application we have the class Automóvel:

public class Automovel {
    private String marca;
    private String matricula;
    private String anoConstrucao;
    private Motor motor;
    private int preco = 0;

With their manufacturers, getters and setters.

And there’s a class called Motor which is a class attribute Automovel.

Class Motor:

private int potencia;

    public Motor() {}

    public Motor(int potencia){
        this.potencia = potencia;
    }

    public int getPotencia() {return this.potencia;}

    public void setPotencia(int potencia) {
        this.potencia = potencia
}

There are also 2 subclasses of this class (the MotorEletrico and the MotorCombustão):

public class MotorEletrico extends Motor {

    private int autonomia;
    public MotorEletrico() {}

    public MotorEletrico(int potencia, int autonomia) {
        super(potencia);
        this.autonomia = autonomia;
    }

    public int getAutonomia() {
        return autonomia;
    }

    public void setAutonomia(int autonomia) {
        this.autonomia = autonomia;
    }

}

And:

public class MotorCombustao extends Motor{

    private int cilindrada;
    private String combustivel;

    public MotorCombustao(){}

    public MotorCombustao(int potencia, int cilindrada, String combustivel){
        super(potencia);
        this.cilindrada = cilindrada;
        this.combustivel = combustivel;
    }

    public int getCilindrada(){
        return cilindrada;
    }

    public void setCilindrada(int cilindrada){
        this.cilindrada = cilindrada;
    }

    public String getCombustivel(){
        return combustivel;
    }

    public void setCombustivel(String combustivel){
        this.combustivel = combustivel;
    } 
}

I store an automobile with a motorX in one array object Automovel, but when I will try to access the getters and setters sub-class (MotorEletric/Combustao), only gets and sets of the mother class appear (Motor).

My problem is I can’t access getters and setters of motor subclasses. Here is an example of what I tried:

        Automovel arrayteste[] = new Automovel[49];

        Motor motor1 = new MotorEletrico();
        motor1.setPotencia(5);

        Automovel automovel1 = new Automovel("Opel", "xx-12-xx", "2000", motor1, 2000);

        arrayteste[0] = automovel1;

        System.out.println(arrayteste[0].getMotor().getPotencia()); //Aqui, eu não consigo fazer o .getAutonomia
  • Did the answer solve your question? Do you think you can accept it? See [tour] if you don’t know how you do it. This would help a lot to indicate that the solution was useful to you. You can also vote on any question or answer you find useful on the entire site.

2 answers

6

In essence does not access, at least not directly and correctly. If you have a field (attribute is the wrong term) or methods getter/Setter unique to the sub class it can only be accessed on objects treated as its specific type. In its class Automovel you have a field treated as a more general object, so you should only access the members that are available in it.

What you’re trying to do is abstraction leak. You are obliged to know that the objects there have inheritance and can be of certain types. What’s more, you have to know what types exist, so the reason for making an inheritance is lost (yes, most people make an inheritance and they don’t even know why, because they saw another one doing it). The use of inheritance is precisely to not have to know who the child classes are. Daughters know the mother, but not the opposite. Even has technique for it, but most of the time is wrong, one of the reasons it is even "difficult" to do.

If you really want to do this you would have to check what the actual type of object is, make a cast for this type and then you can call the desired method because now it is of the specific type. This is conceptually wrong. If you want to see, I already answered how to do in Parent class array with two different subclasses.

Can still help: Follow the OCP principle or use "instanceof". And to see that right is another way, but you can do it anyway: How to store values in a vector using inheritance/polymorphism? (note that the accepted answer is not the correct form).

Think about it, it’s not even a rule of speech, if you know what method to call then you know what method it is. What the compiler does is just force you to say that you know, because there’s a good chance you’re doing it wrong. Without a cast the guy is Motor and not MotorEletrico. In Motor has no method getAutomnomia().

1

Unfortunately, according to your modeling, this is not possible without using a cast class Motor for MotorEletrico:

Motor motor = arrayteste[0].getMotor();
MotorEletrico motorEletrico = (MotorEletrico) motor;

The above technique is known as downcasting, which is the cast parent-class (Motor) for a daughter class (MotorEletrico).

So, finally, you will be able to access the method getPotencia():

System.out.println(motorEletrico.getAutonomia());

However, it hardly makes sense to do the cast without first verifying what is the instance of Motor, as in the case of Motor were MotorCombustao you would receive an error. For our luck, this can be checked before using the operator instanceof.

The final code could then be:

Motor motor = arrayteste[0].getMotor();

if (motor instanceof MotorEletrico) {
    MotorEletrico motorEletrico = (MotorEletrico) motor;
    System.out.println(motorEletrico.getAutonomia());
}

Browser other questions tagged

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