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

限于喜欢 提交于 2019-12-29 03:22:33

问题


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?


回答1:


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();



回答2:


I'm rewriting your code here with some modification. Please look at the changes.

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();
    }
    ...
    ...
    //This method is not overridden.
    void methodInSuper(){
        System.out.prinln("method not overridden.");
    }
}
class sub extends superclass{
    int num=5;
    ...
    ...
    //This is only in subclass.
    void methodInSub(){
        System.out.println("method only in subclass.");
    }
}

Now when you are creating an object like this:

superclass s1=new sub();

Then you can call all the overridden methods like

s1.supermethod();
s1.method();

In this case the methods of subclass will be called.
you can also call methods of superclass those are not overridden like

s1.methodInsuper();

but if you try to access method defined only in subclass like

s1.methodInsub();

then it will be a compile time error.


It is becoz s1 is of type Superclass.
If you still want to call the method in subclass then you need to typecast s1 to subclass like

Sub s = (Sub) s1;

After that you can call the method of the subclass.
And if you create an object like

Sub s2 = new Sub();

Then you can access any methods defined in subclass or superclass.

The earlier creation of object is basically used for implementing "Run Time Ploymorphism".
Hope you got your answer.




回答3:


you are creating Object of sub and assigning it to super's reference.if you dont 1)first case:-

superclass s=new sub();   
        s.supermethod();
        s.method();

in above case methods of sub will be called but these two method should be present in superclass also(if not present then compile time error)

2)second case:-

sub s=new sub();   
    s.supermethod();
    s.method();

in this also methods of sub will be ,these method may or may not be present super.




回答4:


let's take an example: sup is a reference variable for a class A's objects. and sub is a reference variable for a class B's objects. let's suppose B extends A . so if we write "sup = sub;" or "sup = new B();" this statement enables us to get the attributes that are common between the 2 classes . i.e : the attributes that were inherited by B ... we use this trick to check for attributes inherited by B and were changed.



来源:https://stackoverflow.com/questions/24807029/superclass-reference-to-subclass-object-showing-same-behaviour-as-subclass-refer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!