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

Create an array of superclasses while maintaining polymorphic attributes

如果我有一个在 运行 时间内填充的 Birds 数组,我如何才能访问特定于子 classes 的成员方法?

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!
}

有没有一种好方法既能拥有一组泛型类型又能访问特定于子 class 的成员函数?我不想编辑 Bird class.

理论上是的。放在数组中的项目是可具体化的,因此您可以确定您正在查看的类型并将特定对象转换为它的实际类型。不过,这不是一个非常干净的解决方案,所以我不推荐它。

您可以考虑使用一个抽象 class 或表示鸟的接口,它具有 大多数 鸟会支持的方法,以及检查方法 canSing()canFly()。如果您尝试调用鸟类不支持的方法,不支持此功能的鸟类(例如不会飞的鸟类)可能会抛出 UnsupportedOperationException,但是没有简单的方法可以通用地引用所有鸟类并了解所有情况每个子类型的鸟可以有不同的方法。

只是为了从评论中删除我的回答。

切换到使用列表而不是数组,当你拉出你的特定鸟时,你需要将它转换为 "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();
    }
}