在保持多态属性的同时创建一个超类数组

时间:2015-02-22 14:41:49

标签: java arrays arraylist polymorphism

如果我在运行时填充了一系列Birds,那么如何访问特定于子类的成员方法呢?

class Bird
{
  public Bird() {}
  public void fly(int x) {
     System.out.println("Flew "+x+" meters");
  }
}
class DumbBird extends Bird
{
   public DumbBird() {super();}
   public void fly(int x) {
     x-=5; //we're dumb
     System.out.println("Flew "+x+" meters");
   }
   public void sing() {
      System.out.println("La la la!");
   }
}
public static void main(String[] args)
{
   Bird[] cage = new Bird[10];
   cage[0] = new Bird();
   cage[1] = new Dumbbird();
   cage[2] = new Sleepybird();
   //.... more bird types

   cage[1].sing(); //is inaccessable because it is of type Bird not DumbBird!
}

是否有一种很好的方法可以拥有一个泛型类型数组,同时能够访问特定于子类的成员函数?我不想编辑Bird类。

2 个答案:

答案 0 :(得分:5)

理论上,是的。放入数组的项目是可以恢复的,因此您可以确定要查看的类型,并将特定对象强制转换为实际类型。但这不是一个非常干净的解决方案,所以我不推荐它。

您可以考虑使用一个抽象类或接口代表鸟类,其中包含大多数鸟类支持的方法,以及检查方法canSing()canFly()。如果你试图调用鸟不支持的方法,那些不支持此类的鸟类如不会飞的鸟类会抛出UnsupportedOperationException但是没有简单的方法可以一般性地引用所有的鸟类而且知道所有的鸟类每种子类型的鸟可以有不同的方法。

答案 1 :(得分:1)

只是从评论中删除我的答案。

切换到使用列表而不是数组,当您拉出特定的鸟时,您需要将其强制转换为正确的“Bird”类型,请参阅下面的代码示例:

import java.util.ArrayList;

class Bird
{
  public void fly(int x) {
     System.out.println("Flew "+x+" meters");
  }
}

class DumbBird extends Bird
{
   public void fly(int x) {
     x-=5; //we're dumb
     System.out.println("Flew "+x+" meters");
   }

   public void sing() {
      System.out.println("La la la!");
   }
}

class Test {
    public static void main(String[] args)  {
       ArrayList<Bird> cage = new ArrayList<Bird>();
       cage.add(new Bird());
       cage.add(new DumbBird());
       cage.add(new Bird());
       cage.add(new DumbBird());
       cage.add(new SleepyBird());

       ((DumbBird) cage.get(1)).sing();
    }
}