如何访问子 class 中的获取和设置?

How can I access gets and sets in a sub class?

在此应用程序中,我们有 Automovel class:

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

(及其构建器、getter 和 setter)还有一个名为 Motor 的 class,它是 Automovel class.

的一个属性

电机Class:

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
}

这个 class 也有 2 个子class(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;
    }

}

电机燃烧:

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 对象数组中,但是当我尝试访问子class (MotorCombustao / MotorEletrico) 的 getter 和 setter 时,只有 gets 和 sets母亲 class (Motor) 出现了。我的问题是我无法访问电机 subclasses 的 getter 和 setter。 这是我尝试过的示例:

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()); //Here, I can't Do .getAutonomia

简答

你需要投

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 电机和 向上转换(转换为超类型)总是被允许的。

在你的情况下,你必须做 向下转换:你告诉编译器 arraytest[0].getMotor() 包含一个 Motor 但是这个 Motor 实际上是一个 MotorElectrico:你要求编译器信任你。如果在编译时 arraytest[0].getMotor() 不应该是 MotorElectrico 你会得到 ClassCastException.

你需要将父class的引用转换为相应的子class 如果你想访问一个不是从父[=34继承的方法=] 例如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());
        }
    }
}

我假设您熟悉 Liskov substitution principle。 如果你不知道电机的类型,你可以写一个语句来询问 Automovel 数组 arraytest[i] 的每个实例是什么 class 。 例如:

    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 . . .");
        }
     }
}

但更仔细地探索 class 设计可能会更好。 可能尝试使用接口。