Inheritance in Java simple clarification

﹥>﹥吖頭↗ 提交于 2019-12-25 04:59:10

问题


So, I have this:

public class A {

    public int a = 0;
    public void m(){
        System.out.println("A"+a);
    }
}

And this:

public class B extends A {

    public int a = 5 ;
    public void m (){
        System.out.println("B"+a);
    }
    public static void main(String[] args) {
        A oa = new A();
        B ob = new B();
        A oab = ob;
        oa.m();
        ob.m();
        oab.m();

        System.out.println("AA"+oa.a);
        System.out.println("BB"+ob.a);
        System.out.println("AB"+oab.a);
    }
}

Output:

A0
B5
B5
AA0
BB5
AB0

I don't understand why oab.m(); output is B5 instead of A0. Can someone explain this to me?


回答1:


That's the whole point of polymorphism. The concrete type of oab is B (since the object was created with new B()). So the method B.m() is called.

Look at the Animal example in http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29 to understand why it's useful. When you have an animal, and this animal is a Cat, you expect it to say "Meow!" when you make it talk.




回答2:


B ob = new B();
A oab = ob;

Similar as

A oab=new B();

I don't understand why oab.m(); output is B5 instead of A0

Because you creating object of B and referencing it to A so m() is being inherited and that's why B's version of m()is being called.




回答3:


A oa = new A();
B ob = new B();
A oab = ob;

From the code above ob is an instance of class B. It can be stored in a variable of class A as A extends B. But as the stored Object instance is of B and hence it is not aware of A's m() function. Hence the out put is B5




回答4:


In inheritance actual method invocation depends on the type of the actual object and not on the type of the reference.

 B ob = new B();
 A oab = ob;

Here oab is a reference variable of type A but it is pointing to object of type B i.e. ob so at runtime oab.m() will invoke overridden m() method from class B




回答5:


In Java there is something like late binding (polymorphism). It means that code of method is not linked while compilation time (early binding), but while runtime. While invoking oab.m(); JVM is checking actual type (class) of object from aob reference (in your case B) and based on that info invoking code of method from that class. That is why oab.m(); returns B5.

You also need to know that late binding works only for methods, not fields. For fields value will be determined by reference type, so oab.a will return 0 not 5.




回答6:


Imagine you had the following:

public class C extends A {

public int a = 7 ;
public void m (){
    System.out.println("C"+a);
}

Now if you had this in your Main method...

C oc = new C();
A oac = oc;
oac.m();

...you would want that last call to output the stuff that is specific for the class C.

The point is that B is an A, and C is an A, but each of them have more specific versions of the values that an A contains, and when you ask for those data, the specific versions of them should be returned.

Now you can do this:

// Get an instance of B or C, but you don't
// care which - could be either:
A someVersionOfA = getAnInstanceOfA(); 

// This works no matter if you've got an instance
// of B or C, but the result should vary accordingly:
someVersionOfA.m();

As someone else mentioned, think of A as "Animal", B as "cat", and C as "Dog". If m() means "Make some noise", then calling m() should result in "Meow" or "Woof!" depending on on the instance getAnInstanceOfA() returned.




回答7:


You have just copied the internal address of B to A one, and replacing it.

B inherit from A, so no compilation problem.

Finally, the reference to A is destroyed, it is now a copy of reference to B



来源:https://stackoverflow.com/questions/11327514/inheritance-in-java-simple-clarification

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