我有一个名为Student
的类和一个名为AthleteStudent
的子类:
public class Student {
protected String name;
protected String age;
public void hello () {
system.out.println("Hello I'm Student");
}
}
public class AthleteStudent extends Student {
protected String sport;
public void hello () {
system.out.println("Hello I'm AthleteStudent");
}
public void changeDepartement() {
.....
}
}
现在让我们来看看这些测试用例:
AthleteStudent ats = new AthleteStudent("test", 22, "Karate");
Student std;
std = ats; // upcasting OK
/* ats and std point to the same object, i.e AthleteStudent */
ats.hello(); /* Hello I'm AthleteStudent => polymorphism OK */
std.hello(); /* Hello I'm AthleteStudent => polymorphism OK */
这里我不明白的是这个:
即使std
引用AthleteStudent
,我也无法访问方法changeDepartement()
。
std.changeDepartement(); // Doesn't work
只有当我们像这样投射这个物体时才能运作
((AthleteStudent) std).changeDepartement(); // OK
为什么我们需要强制std
成为AthleteStudent
对象,因为它知道它被视为AthleteStudent
个对象?在第一个示例中,std.hello()
打印出AthleteStudent
实现中没有问题的那个。
答案 0 :(得分:8)
这不是多态性的丧失。这是duck typing的缺失。当编译器静态地只知道它是Student
时,它不允许你调用非Student
方法。即使您知道,在运行时,java的静态类型系统也可以使用。其他语言有鸭子打字,不关心。 Java不是其中之一。
答案 1 :(得分:4)
std
的类型为Student
,它可能包含对不是AthleteStudent
的对象的引用。因此,如果没有明确转换为std.changeDepartement()
,则无法致电AthleteStudent
。