public class AnimalExample1  // *** CONTAINS REDUNDANT CODE FOR NAME, MOVING ***
{
    public static void main(String[] args)
    {
        Animal[] circus = new Animal[4];
        circus[0] = new Bird("Tweety");
        circus[1] = new Elephant("Dumbo");
        circus[2] = new Horse("Shadowfax");
        circus[3] = new Bird("Daffy");

        for (int k = 0; k < circus.length; k++)
            perform(circus[k]);
    }

    public static void perform(Animal a)
    {
        System.out.println("=== " + a.getName() + " ===");
        a.move();
        a.speak();
        a.speak();
        a.move();
    }
}

interface Animal
{
    abstract public String getName();
    abstract public void move();
    abstract public void speak();
}

class Bird implements Animal
{
    Bird(String nm)         { name = nm; }
    public String getName() { return name; }
    public void move()      { System.out.println("fly"); }
    public void speak()     { System.out.println("chirp"); }

    private String name;
}

class Horse implements Animal
{
    Horse(String nm)        { name = nm; }
    public String getName() { return name; }
    public void move()      { System.out.println("walk"); }
    public void speak()     { System.out.println("neigh"); }

    private String name;
}

class Elephant implements Animal
{
    Elephant(String nm)     { name = nm; }
    public String getName() { return name; }
    public void move()      { System.out.println("walk"); }
    public void speak()     { System.out.println("trumpet"); }

    private String name;
}
