Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Superclass reference to subclass object showing same behaviour as subclass reference to subclass object

The following code in java, when run on elipse, gives same output even if we replace

superclass s=new sub();

with,

sub s= new sub();

Note that we have overridden methods.

Output is:

changed supermethod in sub class
num is sub class 5

Code:

public class superclass {
    int num=2;
    public static void main(String str[]){
        superclass s=new sub();
        //HERE: nothing changes if we write, sub s=new sub();
        s.supermethod();
        s.method();
    }
    void supermethod(){
        System.out.println("supermethod as in superclass");
    }
    void method(){
        System.out.println("num in superclass "+num);
    }
}
class sub extends superclass{
    int num=5;
    void method(){
        System.out.println("num is sub class "+num);
    }
    void supermethod(){
        System.out.println("changed supermethod in sub class");
    }
}

Please point out, what are the differences in creating a sub class object in these two ways. And will there be any difference in accessing methods and variables? (our java teacher says, accessing method and variables will be different in both cases)

Also, what happens to the static methods, like main. Tough i know it is inheritable, but can someone highlight its behavior in sub classes?

like image 967
nishantbhardwaj2002 Avatar asked Jul 17 '14 14:07

nishantbhardwaj2002


1 Answers

In Java, all non-static methods are "virtual", meaning that they are based on the runtime type of the underlying object rather than the type of the reference that points to that object. Therefore, it doesn't matter which type you use in the declaration of the object, the behavior will be the same.

What the declaration does affect, is the methods that are visible at compile-time. If SubClass has a method that SuperClass does not (let's call it subMethod()), and you construct your object as

SuperClass s = new SubClass();

Then you will only be able to call methods on it that are available on SuperClass. That is, attempting to call s.subMethod() will give you a compile time error. But, as you have discovered, if there methods are present in SuperClass, but overridden by SubClass, it will be the overridden method that will be executed.

Static methods, on the other hand, are not virtual. Running the code below

public class StaticTest {
    public static void main(String[] args) {
        SuperClass s = new SubClass();
        s.method();  // bad idea - calling static method via an object reference
    }

    public static class SuperClass {
        public static void method() {
            System.out.println("SuperMethod");
        }
    }

    public static class SubClass extends SuperClass {
        public static void method() {
            System.out.println("SubMethod");
        }
    }
}

prints out "SuperMethod". You should rarely care, however, that static methods are non-virtual because you should never call them via an object reference as I have done above. You should call them via the class name:

SuperClass.method();
like image 108
matt forsythe Avatar answered Oct 13 '22 02:10

matt forsythe