Java 中的多态性问题

Polymorphism issue in Java

我有一个多态数组,我需要修复底部的两行代码。 我无法理解多态性,我正在尝试弄清楚它的逻辑。

在此代码中,我假设 Animal = 超类,Dog = 子类,Cat = 子类:

Animal[] animals = new Animal[20];
animals[0] = new Dog();
animals[1] = new Cat();

//these two below don't work
Dog lassie = animals[0];
Cat fluffy = animals[1];

不行,因为数组的类型是Animal,也就是说数组中的对象都是Animal类型的。您正在将 DogCat 的单个元素分配给该特定动物的引用,但该对象的类型为 Animal,即使实际元素是 DogCat。如果没有强制转换,编译器不知道 Animal 种类。

要使该语句生效,您需要转换为适当的类型。

Dog lassie = (Dog) animals[0];
Cat fluffy = (Cat) animals[1];

不过,多态性并没有真正以这种方式使用,因为这个想法是作为用户的你,不需要知道 Animal 的具体类型,只需要知道它是一个 Animal.

假设您的 Animal class 定义了一个名为 speak() 的抽象方法并且您的子 class 都实现了它,System.out.println("Woof") 对于 DogSystem.out.println("Meow")Cat,以保持简单。

示例:

public abstract class Animal {
   public abstract void speak();
}

public class Dog extends Animal {
   @Override
   public void speak() {
       System.out.println("Woof!");
   }
}

public class Cat extends Animal {
   @Override
   public void speak() {
       System.out.println("Meow!");
   }
}

如果你的数组是这样的:

Animal[] animals = new Animal[20];
animals[0] = new Dog();
animals[1] = new Cat();

for (Animal a : animals) {
    a.speak();  // you don't know what Animal it is, but the proper speak method will be called.
}

那不是多态性的使用方式。这个想法是,一旦将元素添加到多态集合中,就应该将它们全部视为 Animal。如果它们有不同的行为,那么这将进入在超类上定义并在子类中实现的多态方法。如果不清楚,请告诉我。

您正在尝试将类型 Animal 分配给 Dog(假设 Dog 继承自 Animal),分配无法工作,因为编译器只能保证对象是 Animal 类型,它可能是 Horse 它所知道的

但是您可以再次将 Animal 转换为 DogCat,假设 DogCat 继承自 Animal

Dog lassie = (Dog)animals[0];
Cat fluffy = (Cat)animals[1];

话虽如此,我会非常小心以这种方式盲目转换值。

当定义一个数组为Animal时,你基本上是在说,我不关心内容,只要它满足class/interfaceAnimal的约定要求即可,除此之外,你不应该关心

animal[0]animal[1] 的静态类型是 Animal。所以基本上你是在告诉 java:

让这个Dog lassie成为一只动物。让这个 Cat fluffy 成为一只动物。但并非所有动物都一定是猫或狗。明白为什么 Java 会对此感到不安吗?

你需要使用种姓来安抚Java:

Dog lassie = (Dog) animals[0];
Cat fluffy = (Cat) animals[1];