0

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?

Pshemo
  • 122,468
  • 25
  • 185
  • 269
Falco
  • 1
  • 1

7 Answers7

9

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.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • The method `m()` is overridden in `class B`. Both `class A` and `class B` have the same method signature for `m()`. It is the most specific method that is called and as `oab` is an instance of `class B`, it is `b.m()` that is called. The variable `oab` is simply being referenced as type `A`. – mrswadge Jul 04 '12 at 11:11
1
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.

amicngh
  • 7,831
  • 3
  • 35
  • 54
0
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

Akhi
  • 2,242
  • 18
  • 24
  • `oab` is aware of the fact that that there is a function `void m()`, since class A has that function defined. However, since the implementation of the function is overridden in class B, which is the real type of the object, it calls the implementation of `void m()` in class B. – nhahtdh Jul 04 '12 at 10:49
  • that is it nhahtdh. What puzzled me most was that i've put the method **void m()** in class A as comment, and then **oab** stopped beind aware of **void m()**. that makes sense, thank you – Falco Jul 04 '12 at 11:29
0

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

Ajinkya
  • 22,324
  • 33
  • 110
  • 161
0

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.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
0

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.

Kjartan
  • 18,591
  • 15
  • 71
  • 96
0

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

cl-r
  • 1,264
  • 1
  • 12
  • 26