【问题标题】:Java polymorphism casting - runtime error ClassCastExceptionJava 多态性转换 - 运行时错误 ClassCastException
【发布时间】:2018-07-23 03:24:15
【问题描述】:

我这里有这段代码:

public class code {

    public static void main(String args[]){

        Animal ani1 = new Animal();
        Animal ani2 = new Dog();

        Dog d1 = (Dog)ani1; //runtime error ClassCastException
        Dog d2 = (Dog)ani2;
    }
}

class Animal {
    public String name = "animal";
    public void talk(){
        System.out.println("Animal");
    }
}

class Dog extends Animal {
    public String name = "dog";
    public void talk(){
        System.out.println("Dog");
    }
}

我不明白为什么会发生运行时错误并且通常会向下转换。创建了 2 个对象,一个 Animal 对象和一个 Dog 对象。每个都由Animal 类型的变量引用。

我认为 Java 不会分配 d1 类型为 Animal 的对象,因为 d1 被声明为类型 Dog。但令我困惑的是ani1ani2 都是Animal 类型,并且应该能够向下转换为Dog 对吧?唯一的区别是一个引用Animal 对象,另一个引用Dog 对象。

Java 是否知道 ani1 正在引用 Animal 对象并且不允许为 d1 分配引用 Animal 对象的变量?

【问题讨论】:

  • 如果你写Object x = new Object();,你能把x转换成一个字符串吗?不,你不能,因为它不是字符串。强制转换不会改变 是什么; 它只会改变你的代码识别它的方式。如果您的对象还不是 Dog 实例,则强制转换它不会将其更改为 Dog 实例。你如何选择引用你的对象并不能决定它们实际上是什么。
  • ...既然你问了,Java 知道一个对象的内部类型,尽管变量被声明为什么。这就是instanceof 运算符起作用的原因。尽管 ani2 被声明为 Animalani2 instanceof Dog 仍将返回 true。

标签: java casting polymorphism


【解决方案1】:

comment by VGR 是正确的,但让我详细说明您的具体情况。狗是动物,但动物不一定是狗。您可以创建Dog 对象并将它们作为Animal 对象传递,但不能反过来。处理此问题的常用方法如下:

public static void main(String args[]) {        
    Dog dog = new Dog();
    makeMeTalk(dog);
}

public static void makeMeTalk(Animal animal) {
    animal.talk();
}

它的输出是:Dog

【讨论】:

    【解决方案2】:

    VGR 说的是对的,你无法改变事物的本质。强制转换只是为了帮助我们的代码在编译期间识别它是什么。

    考虑 ff 示例:

    Animal ani1 = new Cat();
    Animal ani2 = new Dog();
    
    Dog dog1 = (Dog) ani1; // will produce a runtime error
    Dog dog2 = (Dog) ani2;
    

    就像给定的示例一样,您不能通过简单的转换将Cat 简单地更改为DogDog 将始终是 Animal,但 Animal 不能始终是 Dog

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-14
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-22
      相关资源
      最近更新 更多