// using references and inheritance
//
// What happens when assigning a reference of an inherited object
// to a reference of the object of the parent?

class Mammal {
    String name;
    Mammal(String name) {
	this.name = name;
    }

} // class Mammal

class Horse extends Mammal {
    Horse(String name) {
	super(name);
    }

} // class Horse

public class polym1 {
    public static void main(String args[]) {

	Mammal m1 = new Mammal("mammal");
	Horse h1 = new Horse("horse");

	// print out current names
	System.out.println("Test1");
	System.out.println(m1.name);
	System.out.println(h1.name);

	// make m1 refer to same object as h1
	//    h1 refers to an object of class Horse.
	//    m1 refers to an object of class Mammal.
	//    A horse is a mammal.
	//    So, you can make m1 (Mammal) refer to h1 (Horse)
	m1 = h1;

	// print out names
	System.out.println("Test2");
	System.out.println(m1.name); // m1 now accesses h1 variables
	System.out.println(h1.name); // h1 is unchanged

	// now try the reverse assignment
	Mammal m2 = new Mammal("mammal");
	Horse h2 = new Horse("horse");

	// The following won't work!
	// h2 = m2;
	//    h2 refers to an object of class Horse.
	//    m2 refers to an object of class Mammal.
	//    A mammal isn't necessarily a horse.
	//    So, you can't make h2 (Horse) refer to m2 (Mammal)
	// You could try to go "backwards" using an explicit cast:
	// h2 = (Horse)m2;
	// But, Java now reports a runtime exception:
	//    java.lang.ClassCastException: Mammal
        //	      at polym1.main(Compiled Code)

    } // method main
} // class polym1

/* Output:
Test1
mammal
horse
Test2
horse
horse
*/
