Create an array of superclasses while maintaining polymorphic attributes

If I had an array of Birds that is filled during run-time, how can I access member methods specific to child 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!
}

Is there a good way to be able to have a an array of generic types while being able to access member functions specific to a child class? I would like to not have to edit the Bird class.

Answer

Just to remove my answer from the comments.

Switch to using lists instead of arrays and when you pull your specific bird out, you will need to cast it to the correct type of “Bird”, see the below code example:

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

Leave a Reply

Your email address will not be published. Required fields are marked *