明天我有一个测试,我对java中的继承有疑问。
问题: 假设java中的程序,其中Y是X的子类。假设以下代码在程序中有效:
Y[] vetY = new Y[3];
X[] vetX = vety;
以下作业是否在此计划中有效?对齐。
vetX[0] = new X();
我的回答(不确定):它无效,因为vetX
有Y
的方法,我不知道在Y中实现了什么。所以它可以编译但是不会运行
答案 0 :(得分:3)
你的假设是正确的。
通过new Y[3]
创建的数组只能包含Y
类型的对象或其子类。它不能存储超类的实例,例如X
,因为X
存在Y
无法使用所有方法的风险,因此即使< / p>
vetx [0] = new X();
编译正常(vetx是X[]
的类型,因此编译器在这里看不到任何错误),稍后您可以尝试通过vetY
(类型为{{1}来访问此对象}}并尝试调用
Y[]
vety[0].getPropertyAddedInY();
的哪个实例不会。
所以为了防止这种情况在运行时,每个数组都会检查某人试图放入哪种类型的数据,如果不支持,则会抛出X
。
答案 1 :(得分:0)
编译很好,因为编译器看到我们正在定义对其类型的引用。 但是在运行时JVM看到它被预先声明为存储子类型,并且在尝试存储父类型时,反向定义(子引用=父obj)是不可能的,因此抛出异常。
通过以下示例可以更好地理解 -
class X {
public void xMetod() {
System.out.println("Called xMetod!");
}
}
class Y extends X {
public void yMethod() {
System.out.println("Called yMethod!");
}
}
public class InheritanceWithArrays {
public static void main(String[] args) {
X[] vetx= new Y[3]; // if new X[3] - then outputs in Called xMetod!
vetx [0] = new X(); // Runtime exception- java.lang.ArrayStoreException: X
vetx[0].xMetod();
}
}