Как я могу получить доступ и получает в подклассе? - PullRequest
0 голосов
/ 01 февраля 2020

В этом приложении у нас есть класс Automovel:

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

(с их строителями, геттерами и сеттерами), а также есть класс Motor, который является атрибутом класса Automovel.

Класс двигателя:

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
}

Существует также 2 подкласса этого класса (MotorEletrico и MotorCombustao):

Motor Elétrico:

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;
    }

}

Motor Combustão:

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;
    } 
}

Я храню автомобиль с X-двигателем в массиве объектов Automovel, но когда я пытаюсь получить доступ к получателям и установщикам подкласса (MotorCombustao / MotorEletrico), только получатели и наборы матери класс (мотор) появляется. Моя проблема в том, что я не могу получить доступ к получателям и установщикам подклассов двигателя. Вот пример того, что я попробовал:

Automovel arrayteste [] = новый 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()); //Here, I can't Do .getAutonomia

Ответы [ 3 ]

3 голосов
/ 01 февраля 2020

Короткий ответ

Вам необходимо разыграть

System.out.println(((MotorElettrico)(arrayteste[0].getMotor())).getAutonomia());

TL; DR

Когда вы написали

Motor motor1 = new MotorElettrico();

вы используете полиморфизм .

Это очень полезно, когда, например, у вас есть список Motor, который содержит более одного типа двигателя, и для всего этого вы хотите напечатать potencia.

Затем вы можете написать что-то вроде этого:

List<Motor> list = Arrays.asList(new MotorElectico(), new MotorCombustao());
// ----- some set

print(list);

, где метод печати выглядит примерно так:

public void print(List<Motor> list){
    for(Motor m : list){
        System.out.println(String.format("Potencia %d", m.getPotencia()));
    }
}

Это происходит потому, что MotorElectico IS A Motor и upcasting (приведение к супертипу) всегда разрешено.

В вашем случае вы должны выполнить downcasting : вы сообщаете компилятору, что arraytest[0].getMotor() содержит Motor, но это Motor на самом деле MotorElectrico: вы просите компилятор доверять вам. Если во время компиляции arraytest[0].getMotor() не должно быть MotorElectrico, вы получите ClassCastException.

1 голос
/ 01 февраля 2020

Вам нужно привести ссылку родительского класса к соответствующему дочернему классу , если вы хотите получить доступ к методу, который не унаследован от родительского класса , например, метод, getAutonomia() не наследуется от Motor и, следовательно, вам нужно привести значение от Motor к MotorEletrico, прежде чем вы сможете получить доступ к getAutonomia(). Ниже приведен более полезный код:

public class Main {
    public static void main(String[] args) {
        Automovel arrayteste[] = new Automovel[2];
        Motor motor;

        motor = new MotorEletrico(5, 10);
        arrayteste[0] = new Automovel("Opel", "xx-12-xx", "2000", motor, 2000);

        motor = new MotorCombustao(7, 4, "xx-yy-zz");
        arrayteste[1] = new Automovel("Opel", "xx-08-xx", "1995", motor, 1995);

        for (Automovel automovel : arrayteste) {
            motor = automovel.getMotor();
            if (motor instanceof MotorEletrico) {
                System.out.println(((MotorEletrico) motor).getAutonomia());
            }
            if (automovel.getMotor() instanceof MotorCombustao) {
                System.out.println(((MotorCombustao) motor).getCilindrada());
                System.out.println(((MotorCombustao) motor).getCombustivel());
            }
        }
    }
}

Вывод:

10
4
xx-yy-zz

[Обновление: следующее обновление на основе вашего комментария]

Другой способ итерации arrayteste приведен ниже:

for (int i = 0; i < arrayteste.length; i++) {
    if (arrayteste[i] != null) {
        motor = arrayteste[i].getMotor();
        if (motor instanceof MotorEletrico) {
            System.out.println(((MotorEletrico) motor).getAutonomia());
        }
        if (arrayteste[i].getMotor() instanceof MotorCombustao) {
            System.out.println(((MotorCombustao) motor).getCilindrada());
            System.out.println(((MotorCombustao) motor).getCombustivel());
        }
    }
}
0 голосов
/ 01 февраля 2020

Вы знакомы с принципом замены Лискова , я полагаю. Если вы не знаете тип двигателя, вы можете написать инструкцию, которая спрашивает каждый экземпляр массива Automovel arraytest[i], какой это класс. Например:

    List<Automovel> arrayteste = new ArrayList<>();

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

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

    arrayteste.add(automovel1);

    Motor motor = new Motor();
    String motorClass;
    String[] motorTypes = {"MotorEletrico", "MotorCombustao"};
    Set<String> motorClasses = new HashSet<>(Arrays.asList(motorTypes));

    for (int i = 0; i < arrayteste.size(); i++)
    {
        motorClass = arrayteste.get(i).getMotor().getClass().getName();
        if (motorClasses.contains(motorClass))
        {
            if (motorClass.equals("MotorEletrico"))
            {
                motor = (MotorEletrico)(arrayteste.get(i).getMotor());
            }
            else if (motorClass.equals("MotorCombustao"))
            {
                motor = (MotorCombustao)(arrayteste.get(i).getMotor());
            }
            System.out.println("Automovel #" + i + " : " + motor.getPotencia());
        }
        else 
        {
            System.out.println("Não sei que classe de motor é esse . . .");
        }
     }
}

Но может быть, лучше изучить дизайн класса более подробно. Возможно, попробуйте использовать интерфейсы.

...