我有一个名为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实现中打印了一个示例。

最佳答案

这不是多态性的损失。这是缺少duck typing的原因。当编译器静态地仅知道它是Student时,将不允许您调用非Student方法。即使您知道在运行时也可以使用Java的静态键入系统说“不”。其他语言使用的鸭子类型则无关紧要。 Java不是其中之一。

10-07 17:16