【问题标题】:polymorphism has been lost with casting多态性因铸造而丢失
【发布时间】:2015-04-05 16:34:52
【问题描述】:

我有一个名为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 实现的那个,没有问题。

【问题讨论】:

  • 简单地说,您不能在 Java 中转换对象。但是,您可以在 Java 中转换引用。

标签: java


【解决方案1】:

这不是多态性的损失。这是缺少duck typing。当编译器静态地只知道它是Student 时,它不允许您调用非Student 方法。即使您知道,在运行时,java 的静态类型系统会拒绝它。其他语言有鸭子打字,不会在意。 Java 不是其中之一。

【讨论】:

  • 谢谢,我现在明白为什么会出现这个问题了
【解决方案2】:

stdStudent 类型,它可能包含对不是AthleteStudent 的对象的引用。因此,您不能在没有明确转换为 AthleteStudent 的情况下调用 std.changeDepartement()

【讨论】:

    猜你喜欢
    • 2014-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    相关资源
    最近更新 更多