java - 将子类转换为等于父类(super class)时转换失败

标签 java casting classcastexception

我有点困惑为什么下面的代码不起作用并抛出 ClassCastException:

Person superPerson = new Person("marc", 18);        

        PersonOverwritten subPerson = (PersonOverwritten) superPerson;      
        System.out.println(subPerson);

子类与父类相同:

public class PersonOverwritten extends Person {

    public PersonOverwritten(String nome, int idade) {
        super();
    }

}

当然,如果它们来自不同类型,它应该会失败,但是,为什么这不起作用?

最佳答案

这里用一个简单的例子来说明。想象一下 PersonOverwriting 看起来像这样:

public class PersonOverwritten extends Person {
    public PersonOverwritten(String nome, int idade) {
        super();
    }
    public void pickupSticks() {}
}

很明显你做不到

Person superPerson = new Person("marc", 18);        
PersonOverwritten subPerson = (PersonOverwritten) superPerson;
subPerson.pickupSticks();

因为分配给 subPerson 的对象没有 pickupSticks 方法。

编译器允许您编写这样的代码的原因是,您有一天可能想做这样的事情:

Person person = new PersonOverwritten("marc", 18);        
((PersonOverwritten)person).pickupSticks();

在这种情况下,当然不会出现运行时错误,因为您分配给 person 的对象确实支持扩展接口(interface)。在 Java 1.5 中引入泛型之前,经常会看到类似的情况,并且所有集合在访问它们时都会返回 Object

更新

详细说明一下,Java 使用类型来确定对象履行的契约,而不是直接检查属性。它不像 Python 那样使用鸭子类型。编译器将允许您将 Person 转换为 PersonOverwriting,因为它可能是可能的。运行时将禁止您使用实际的 Person 对象作为 PersonOverwriting,因为根据 Java,它不满足接口(interface)。

关于java - 将子类转换为等于父类(super class)时转换失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49883671/

相关文章:

java - 如何从 src 文件夹访问 Hibernate session ?

java - 如何自动删除项目的所有system.out.println语句包括所有多行Sop语句

c++ - 改变类型而不改变位

java - 在服务器客户端应用程序中使用 ObjectInputStream 发生 ClassCastException

java - 无法找到输入文本元素,在 Selenium 2.47 中尝试了 id、class、name、xpath

java - 具有单独收集功能的流过滤器

java - JUnit 测试用例在泛型方法中转换错误的元素

在 int 和 uint 之间转换的 Golang 成本

java - PriorityQueue 抛出类强制转换异常

Java/泛型/ClassCastException