/*
 * This program defines classes representing pets using inheritance.
 * It also demonstrates the use of polymorphism in Java for calling
 * methods, storing object references in arrays, and passing 
 * arguments to polymorphic methods. 
 * Nadeem Abdul Hamid - CSC120 - Fall 2004 - Berry College
 * See lecture unit 11 slides
 */


public class ThirdPetProgram {

    public static void main(String[] args) {
        Pet[] pets = new Pet[2];
        pets[0] = new Dog("Rufus", 4, true);
        pets[1] = new Cat("Panther", 2, false);

        Vet doc = new Vet();
        
        for (int i = 0; i < pets.length; i++) {
            doc.vaccinate(pets[i]);
        }            

    }
    
    /*
    public static void main(String[] args) {
        //Dog doggy = new Dog("Rufus", 4, true);
        Dog doggy = new Dog("Rufus", 4);
        Cat kitty = new Cat("Panther", 2, false);
        
        doggy.makeSound();
        System.out.print(doggy.getName() 
                            + " likes " + doggy.getFood());
        if (doggy.fetchesPaper()) 
            System.out.println(" and fetches the paper");
        else
            System.out.println(" but can't fetch a paper");
        
        kitty.makeSound();
        System.out.print(kitty.getName() 
                            + " likes " + kitty.getFood());
        if (kitty.catchesMice())
            System.out.println(" and will eliminate pesky rodents");
        else
            System.out.println(" but can't stand mice");
    }
    */
}


class Vet {
    public void vaccinate(Pet p) {
        System.out.println("Vaccinating " + p.getName() + "...");
        p.makeSound(true);
    }
}


class Dog extends Pet {
    
    protected boolean paperFetcher;
    
    /*
    public Dog(String n, int a) {
        name = n;
        age = a;
        paperFetcher = true;               // default
        maxAge = 12;
        sound = "woof woof";
        food = "doggy bites";
        
        System.out.println(name + " is ready to go for a walk!");
    } 
    */
    
    public Dog(String n, int a) {
        this(n, a, true);   // call the full constructor with default
                             // value for paperFetcher initializer
    }
    
    public Dog(String n, int a, boolean getsPaper) {
        name = n;
        age = a;
        paperFetcher = getsPaper;
        maxAge = 12;
        sound = "woof woof";
        food = "doggy bites";
        
        System.out.println(name + " is ready to go for a walk!");
    }    
    
    public boolean fetchesPaper() { return paperFetcher; }
    
}


class Cat extends Pet {
    
    protected boolean goodMouser;
    
    public Cat(String n, int a, boolean mouser) {
        name = n;
        age = a;
        goodMouser = mouser;
        maxAge = 10;
        sound = "meow meow";
        food = "kitty food";

        if (goodMouser)
            System.out.println(name + " is ready to catch some mice!");
        else
            System.out.println(name + " is ready to unroll some yarn!");
    }
    
    public boolean catchesMice() { return goodMouser; }
    
}


class Pet {

    protected String name;
    protected int age;
    protected int maxAge;
    protected String sound;
    protected String food;
    
    public String getName() { return name; }
    public int    getAge()  { return age; }
    public int    getMaxAge() { return maxAge; }
    public String getFood() { return food; }
    
    public void makeSound() { 
        makeSound(false);      // default behavior
    }

    public void makeSound(boolean loud) { 
        if (loud) System.out.println(sound.toUpperCase());
        else System.out.println(sound);
    }
    
}