import javax.swing.JOptionPane;

// This is an example illustrating inheritance and ploymorphism

class SuperClass implements TestInterface<SuperClass> {
    
    String method1() {
        return "method1 in SuperClass\n";
    } // end method1
    String method2() {
        return "method2 in SuperClass\n";
    } // end method2
    public int method(SuperClass x) {
        return 37;
    }
    
} // end SuperClass

class SubClass extends SuperClass {
    
    String method2() {
        return "method2 in SubClass\n";
    } // end method2
    String method3() {
        return "method3 in SubClass\n";
    } // end method3
    
} // end SubClass

public class Example5 {
    
    public Example5() {
        String out = "";
        SuperClass A = new SuperClass();
        out += A.method1();
        out += A.method2(); // Since A refers to a SuperClass object this will call
        // the SuperClass method2
        // out += A.method3(); will not compile since A is a SuperClass variable and
        // method3() is not a member of the SuperClass
        JOptionPane.showMessageDialog(null,out);
        out = "";
        A = new SubClass(); // A superClass varable can be assigned any of it's subclasses
        out += A.method1();
        out += A.method2(); // Since A refers to a SubClass object now this will call
        // the SubClass method2. This illustrates polymorphism
        // out += A.method3(); will not compile since A is a SuperClass variable and
        // method3() is STILL not a member of the SuperClass
        out += ((SubClass)A).method3(); // A SuperClass variable can be cast to any of it's subclasses
        // so the compiler will not complain. Since A refers to a
        // SubClass object here a runtime error will NOT occur
        JOptionPane.showMessageDialog(null,out);
        A = new SuperClass();
        //out += ((SubClass)A).method3(); // A SuperClass variable can be cast to any of it's subclasses
        // so the compiler will not complain. Since A refers to a
        // SuperClass object here a RUNTIME ERROR WILL occur
        SubClass B = new SubClass();
        JOptionPane.showMessageDialog(null,((SuperClass)B).method2());
        TestInterface<SuperClass> x = A;
        A = (SuperClass)x;
    } // end Example5
    
    public static void main(String[] args) {
        new Example5();
    } // end main
    
} // end Example5

interface TestInterface<T> {
    public int method(T x);
}





