简体   繁体   English

Java参数多态性示例

[英]Java Parametric Polymorphism example

I have a question about Parametric Polymorphism. 我有一个关于参数多态性的问题。 How do I determine the actual type and avoid casting If I have a collection with a mix of child types. 如果我有一个混合子类型的集合,如何确定实际类型并避免转换。 For example 例如

    class Animal{

    }

    class Bird extends Animal{
          void fly(){}
    }

    class Dog extends Animal{
          void bark(){}
    }

    ArrayList<Animal> list = new ArrayList<Animal>();

The problem is how do I know which one is which when I iterating through the Animal collection. 问题是当我遍历Animal集合时如何知道哪一个。 Do I need to use instanceof to check the actual type every time? 我是否需要使用instanceof来每次检查实际类型?

    for(Animal animal : list){
          if(animal instanceof Dog){
                ((Dog) animal).bark();
          } 
          else ((Bird) animal).fly();             
    }

If you need to do this, that means that's a common action. 如果您需要执行此操作,则这是常见的操作。 You usually would have this : 您通常会这样:

abstract class Animal {
     abstract void act();
}

class Bird extends Animal{
      void fly(){}
      void act(){
         fly();
      }
}

class Dog extends Animal{
      void bark(){}
      void act(){
         bark();
      }
}

and in your loop you would simply call the act method : 在循环中,您只需调用act方法:

for(Animal animal : list){
    animal.act();
}

You should not have list like that. 您不应该有这样的列表。 Otheriwse instanceof (or .getClass() ), followed by a downcast is the only option. 唯一的其他选择是instanceof (或.getClass() ),然后是向下转换。

Using instanceof would defeat the purpose of Generics. 使用instanceof将破坏泛型的目的。 The point of generics is to define behavior so that you don't care what the types are. 泛型的重点是定义行为,这样您就不必关心类型是什么了。 Example: 例:

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();
    }
}

See? 看到? You don't actually care about what type the animal is at runtime. 您实际上并不在乎运行时动物的类型。 You let the objects do what they're supposed to. 您让对象执行它们应做的事情。

By the way, if you did want only Bird to have a fly() method, then you wouldn't try to call the fly() method on all instances of Animal ... you would have a different List<Bird> 顺便说一句,如果您只希望Bird具有fly()方法,那么您将不会尝试在Animal所有实例上调用fly()方法……您将拥有一个不同的List<Bird>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM