public class Zoo {
  class Animal {
    public void eat() { System.out.println(this + " is eating"); }
    public String toString () { return "Animal"; }
  }
  class Mammal extends Animal {
    public void suckMilk() { System.out.println(this + " is sucking"); }
    public String toString () { return "Mammal"; }
  }
  class Dog extends Mammal {
    public void bark() { System.out.println(this + " is barking"); }
    public String toString () { return "Dog"; }
  }
  public void test () {
    Animal a1 = new Animal();
    Animal a2 = new Mammal();
    Animal a3 = new Dog();
    //
    // What will be printed in each case below?
    //
    System.out.println(a1);
    System.out.println(a2);
    System.out.println(a3);
    a1.eat();
    // a2.suckMilk();
    a2.eat();
    // Dog d1 = a3;
    Dog d1 = new Dog();
    Mammal m1 = d1;
    d1.bark();
    m1.suckMilk();
    d1.suckMilk();
    // Type casts:
    Dog d2 = (Dog)a3;
    // a3.bark();
    d2.bark();
    // Dog d3 = (Dog)a2;
  }
  public static void main(String a[]) {
    Zoo z = new Zoo();
    z.test();
  }
}
