//Chapter 9 inheritance stuff crammed into here //part 3 import java.util.*; public class Inheritance3 { public static void main( String[] args ) { X x1 = new X(); Y y1 = new Y(); x1.m1(); y1.m1(); //m1() overridden (redefined) in Y subclass System.out.println( "**********" ); //OK. so what's the big deal with overriding? //Example: create a bunch of objects from the same class heirarchy //and dump them into some container (Collection or array): Set set = new HashSet(); for (int i=1; i<=10; i++) { //create objects from the classes randomly double rand = Math.random(); if ( rand < .25 ) set.add( new X() ); else if ( rand < .5 ) set.add( new Y() ); else if ( rand < .75 ) set.add( new W() ); else set.add( new Z() ); } //now iterate over the objects: Iterator iter = set.iterator(); while ( iter.hasNext() ) //next returns Object, so cast to top of your class heirarchy (X) ((X)iter.next()).m1(); //will be the overridden m1()! //which overridden m1 to call is determined at runtime. //Benefits: //1. switch logic using instanceof's is not needed. //2. additional subclasses can be created and this iteration still works. } } class X { void m1() { System.out.println( "hello from X m1()" ); } } class Y extends X { //method with same signature (name and argument list) as method in //superclass is an override void m1() { System.out.println( "hello from Y m1()" ); } } //Pretend X and Y are complex classes and the m1 does hairy stuff //specific to each class. //second part: class W extends Y { void m1() { System.out.println( "hello from W m1()" ); } } class Z extends X { void m1() { System.out.println( "hello from Z m1()" ); } }