简体   繁体   中英

Creating objects of a subclass as instances of the superclass in Java

say, I have the following code (it's a quiz question, so I can run it in my IDE but the logic how it's working is not quite clear to me):

public class Test {

    public static void main(String[] args){
        A aInstance1 = new A();
        A aInstance2 = new B();
        A aInstance3 = new C();
        aInstance1.doSth();
        aInstance2.doSth();
        aInstance3.doSth();
    }
}

class A {
    public static void doSth(){
        System.out.println("Doing something in A");
    }
}
class B extends A {
    public static void doSth(){
        System.out.println("Doing something in B");
    }
}

class C extends B {
    public static void doSth(){
        System.out.println("Doing something in C");
    }
}

The output will be the following:

Doing something in A

Doing something in A

Doing something in A

Thus, my first question is: what is the meaning of the declaration like

A aInstance2 = new B();

ie, why to create an object of class B declaring it as an instance of class A? How the properties of aInstance2 as an object of class B change compared to the declaration

B aInstance2 = new B();

?

If I remove the word static from the declaration of the methods doSth() in the classes A, B, and C, the output changes to

Doing something in A

Doing something in B

Doing something in C

Thus, when the methods were static, the method doSth() of class A didn't get overridden by those of the subclasses and the output was always "Doing something in A" produced by the objects of different classes, whereas when it became an instance (non-static) method, it gets overridden (if I'm using the right term here). Why is it so?

Removing the word static you are doing Dynamic Binding , because you are pretty much saying : "Even though i know this object is of type A i want it to behave like a B ".

Adding the word static means you are making that method part of the class[Reference type] ,and each time you are calling :"A dosmth()" he knows it only applies to A so it shows the result of the mothod from the class A.

As to what would you do this?I for one learned about this feature from school and studied it even more when i decided to go to interviews becuase it;s one of the things that the interviewer wants to see if you can handle.

If you don't mind I will post a link with information about Static and Dynamic Binding http://javarevisited.blogspot.ro/2012/03/what-is-static-and-dynamic-binding-in.html

Because static method is based on Reference type .

aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();

So internally it converts into :

A.doSth();
A.doSth();
A.doSth();

Static methods are class methods while non-static ones are instance methods. Therefore, when you call a static method over an instance you are actually calling it over the declared type of this instance. So, all below calls actually performs the same call: A.doSth() since all instances are declared as type A.

aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();

When you remove the static keyword, doSth() method becomes an instance method. Instance methods are performed over objects instead of classes. Moreover, when you re-declare an instance method in a subclass, this method is overriden by the subclass. In your example, class B and C override doSth() . Thus, each class provides its own implementation.

Overriding depends on having an instance of a class. A static method is not associated with any instance of a class so the concept is not applicable.

Making static methods works faster, because there's no need to wait until run-time to figure out which method to call.

Overriding in Java simply means that the particular method would be called based on the run time type of the object and not on the compile time type of it.

Illustration -

  • When doSth() is static:

     A aInstance1 = new A(); A aInstance2 = new B(); A aInstance3 = new C(); aInstance1.doSth(); aInstance2.doSth(); aInstance3.doSth(); 

In the above code, the compiler will decide at compile time that without instance it should be called for A. No overriding.

  • When doSth() is not static:

     A aInstance1 = new A(); A aInstance2 = new B(); A aInstance3 = new C(); aInstance1.doSth(); aInstance2.doSth(); aInstance3.doSth(); 

In the above code, the compiler will decide at run time that the method is not static and should be overridden by there respective instances.

静态方法处于class级别,并且作用于引用类型(==的LHS),与实例级别方法不同,实例级方法是根据实例类型(==的RHS)动态调度的

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM