/*
   This file tests how you can access overriden methods and
   fields is a super class of a super class.
*/

public class TestOverriding
{

   public static void main( String args[] )
   {
       ClassC classc = new ClassC();
       classc.method2();

       System.out.println();
       System.out.println("From within the test class:");

       classc.method1();
       ((ClassB)classc).method1();  // doesn't work
       ((ClassA)classc).method1();  // doesn't work

       System.out.println();

       System.out.println( classc.data );
       System.out.println( ((ClassB)classc).data );
       System.out.println( ((ClassA)classc).data );

   }//main

}//TestOverriding


class ClassA
{
   String data = "data in ClassA";

   void method1()
   {
      System.out.println("method1 from ClassA");
   }
}//ClassA


class ClassB extends ClassA
{
   String data = "data in ClassB";

   void method1()
   {
      System.out.println("method1 from ClassB");
   }
}//ClassB


class ClassC extends ClassB
{
   String data = "data in ClassC";

   void method1()
   {
      System.out.println("method1 from ClassC");
   }

   void method2()
   {
      System.out.println("From within ClassC:");
      method1();
      super.method1();            // go "up" one level
      ((ClassA) this).method1();  // try to go "up" two levels
                                  // this doesn't work for methods
                                  // because of polymorphism
      System.out.println();

      System.out.println( data );
      System.out.println( super.data );           // go "up" one level
      System.out.println( ((ClassA)this).data );  // go "up" two levels
                                                  // this works for fields

      // It is interesting to note that for fields the following two lines
      // are equivalent
      //    super.data
      //    ((ClassB)this).data
      // but for methods, because of polymorphism, the following two lines
      // are not equivalent
      //    super.method1()
      //    ((ClassB) this).method1()
   }
}//ClassC