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
类型的。您正在将 Dog
或 Cat
的单个元素分配给该特定动物的引用,但该对象的类型为 Animal
,即使实际元素是 Dog
或 Cat
。如果没有强制转换,编译器不知道 是 Animal
的 种类。
要使该语句生效,您需要转换为适当的类型。
Dog lassie = (Dog) animals[0];
Cat fluffy = (Cat) animals[1];
不过,多态性并没有真正以这种方式使用,因为这个想法是作为用户的你,不需要知道 Animal
的具体类型,只需要知道它是一个 Animal
.
假设您的 Animal
class 定义了一个名为 speak()
的抽象方法并且您的子 class 都实现了它,System.out.println("Woof")
对于 Dog
和 System.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
转换为 Dog
或 Cat
,假设 Dog
和 Cat
继承自 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];
我有一个多态数组,我需要修复底部的两行代码。 我无法理解多态性,我正在尝试弄清楚它的逻辑。
在此代码中,我假设 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
类型的。您正在将 Dog
或 Cat
的单个元素分配给该特定动物的引用,但该对象的类型为 Animal
,即使实际元素是 Dog
或 Cat
。如果没有强制转换,编译器不知道 是 Animal
的 种类。
要使该语句生效,您需要转换为适当的类型。
Dog lassie = (Dog) animals[0];
Cat fluffy = (Cat) animals[1];
不过,多态性并没有真正以这种方式使用,因为这个想法是作为用户的你,不需要知道 Animal
的具体类型,只需要知道它是一个 Animal
.
假设您的 Animal
class 定义了一个名为 speak()
的抽象方法并且您的子 class 都实现了它,System.out.println("Woof")
对于 Dog
和 System.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
转换为 Dog
或 Cat
,假设 Dog
和 Cat
继承自 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];