我有一个关于参数多态性的问题。如何确定实际类型并避免强制转换如果我有一个混合了子类型的集合。例如
class Animal{
}
class Bird extends Animal{
void fly(){}
}
class Dog extends Animal{
void bark(){}
}
ArrayList<Animal> list = new ArrayList<Animal>();
问题是当我迭代Animal集合时,我怎么知道哪一个是哪一个。我是否需要每次都使用instanceof来检查实际类型?
for(Animal animal : list){
if(animal instanceof Dog){
((Dog) animal).bark();
}
else ((Bird) animal).fly();
}
答案 0 :(得分:6)
如果你需要这样做,那就意味着这是一个共同的行动。你通常会这样:
abstract class Animal {
abstract void act();
}
class Bird extends Animal{
void fly(){}
void act(){
fly();
}
}
class Dog extends Animal{
void bark(){}
void act(){
bark();
}
}
在循环中,您只需调用act
方法:
for(Animal animal : list){
animal.act();
}
答案 1 :(得分:0)
你不应该有那样的清单。其他的instanceof
(或.getClass()
),然后是向下投射是唯一的选择。
答案 2 :(得分:0)
使用instanceof
会破坏Generics的目的。泛型的关键是定义行为,以便您不关心类型是什么。例如:
public interface Animal {
void speak();
void fly();
}
public class Dog implements Animal {
public void speak() {
System.out.println("Woof!");
}
// Do nothing!
public void fly() { }
}
public class Bird implements Animal {
public void speak() {
System.out.println("Tweet!");
}
public void fly() {
System.out.println("I'm flying!!");
}
}
public static void main (String[] args) {
// list populating removed
for(Animal animal : list) {
animal.speak();
animal.fly();
}
}
请参阅?实际上,您并不关心动物在运行时的类型。你让对象做他们应该做的事。
顺便说一下,如果您确实只希望Bird
拥有fly()
方法,那么您就不会尝试在fly()
的所有实例上调用Animal
方法} ...你会有一个不同的List<Bird>