假设编译器忽略了a.sayB()语句的类型检查,因此我们可以运行我们的程序。
运行时会发生什么?
A a = new B();
a.sayB(); // compile time error
...
class A {
public void sayA() {
System.out.println("method of class A");
}
}
class B extends A {
public void sayB() {
System.out.println("method of class B");
}
}
答案 0 :(得分:2)
它会按预期工作,因为您的a
是B
。你可以添加一个演员,并在实践中做。像,
A a = new B();
((B)a).sayB();
答案 1 :(得分:1)
你的问题有点不清楚。你说如果编译器没有阻止你,会发生什么。编译器必须阻止你,因为在编译时,方法调用被解析为需要从声明方法的类中查找的符号。
方法"说B(无效)"并不存在于B类声明的上下文之外。
使用反射你可以说(省略了必要的异常处理):
Method sayBMethod = B.class.getMethod("sayB");
// you now have a reference to the method itself and can try invoking it on your instance
sayBMethod(a)
这将尝试在实例a上调用该方法,并将抛出IllegalArgumentException而不是B.注意即使a是另一种类型也有方法sayB(),它仍然会失败。方法名称已在编译时(在您的示例中)或在我们反映在B类上查找方法时解析。
如果你试过
A.class.getMethod("sayB")
你只是得到一个NoSuchMethodException。