/*
      I
      |
      |
      A     J
       \   /
        \ /
         B
*/

interface I
{
   public int method1(int x);      // declaration
   public void method2(double x);  // declaration
   public String method3();        // declaration
}

interface J
{
   public double method4();
   public void method5();
}

class A implements I
{
   @Override
   public int method1(int x)      // declaration
   {
      return x + 2;
   }

   @Override
   public void method2(double x)  // declaration
   {
      System.out.println(x);
   }

   @Override
   public String method3()        // declaration
   {
      return "hello from method3 in class A";
   }

   public String method3(String s) // declaration
   {
      return "hello from the other method3 in class A";
   }

   public int methodA(int y)  // declaration
   {                          // definition
      return y+1;
   }
}

class B extends A implements J
{
   @Override  // from J
   public double method4()
   {
      return 3.14;
   }

   @Override  // from J
   public void method5()
   {
   }

   void method6()  // not from A or I or J
   {
   }
}

public class Code3
{
   public static void main(String[] args)
   {
      A a = new A();
      B b = new B();
      I c = new A();
      I d = new B();
      A e = new B();
//    B f = new A();  // not allowed
      J g = new B();
//    J h = new A();  // not allowed

//      a.?();
//      b.?();
//      c.?();  // c refers to an A obj
//      d.?();  // d refers to a B obj
//      g.?();

      d.method1(5);
      ((B)d).method6();
   }
}
