user2908206
user2908206

Reputation: 265

Java Inheritance issue - try to understand the concept

i try to understand the Inheritance concept and i have a little question.

I have two classes A and B as:

public class B extends A
{
    public B()
    {
        System.out.println ("B");
    }

    public void arik ()
    {
        System.out.println("Arik_B");
    }
    public void yosef ()
    {
        System.out.println ("Yosef");
    }

    public void superYosef()
    {
        super.yosef();
    }
}

public class A
{
    public A()
    {
        System.out.println ("A");
    }

    public void arik ()
    {
        System.out.println ("Arik_A");
    }

    public void yosef ()
    {
        arik();
    }
}

Main:

A ab = new B();
((B) ab).superYosef();

The line A ab = new B(); will print A B and this is clear. But the line ((B) ab).superYosef(); print Arik_B and i don't understand why. before running ab is type A and while running it's B so it need to print Yosef

Upvotes: 2

Views: 121

Answers (4)

Marko Topolnik
Marko Topolnik

Reputation: 200138

When an instance method is called on this, the only thing that matters is the type of the object on which it is called. This type is known only at runtime.

When an instance method is called on super, dynamic dispatch does not apply. The method is chosen at compile time.

In your code:

  1. you create a new B(); and call B.superYosef();
  2. the call super.yosef(); appearing in that method invokes A.yosef() statically (not subject to dynamic dispatch);
  3. A.yosef() calls this.arik()—unlike above, a method called on this is subject to dynamic dispatch;
  4. the type of this is B, therefore the method B.yosef() is called.

Upvotes: 5

Rohit Jain
Rohit Jain

Reputation: 213193

When you invoke the method:

((B) ab).superYosef();

The actual instance being referred by ab reference is of class B only. Moving further, this invocation will call method superYosef() method in class B. Now, let's go to that method:

public void superYosef()
{
    super.yosef();
}

This will call the yosef() method in class A. Due to super. The instance is still B. And then in yosef() method:

public void yosef ()
{
    arik();  // equivalent to `this.arik();`
}

Here you have reference this holding reference to instance of class B. You invoke arik(), which is overridden in class B, and hence the method arik() of class B is invoked. The only thing which is important here is, the actual object is of type B.

Upvotes: 3

Jesper
Jesper

Reputation: 206776

When you do

A ab = new B();

then the variable ab of of type A, but the actual object that it refers to is of type B. The actual type of the object determines which method will be called, not the type of the variable.

So, when you call any method on ab that has been overridden in class B, the version from class B will be called.

Let's see what happens here:

((B) ab).superYosef();

You need to cast, because the method superYosef is only defined in class B.

That method calls super.yosef();, which will call the yosef method in class A. The A.yosef calls arik, and this method is overridden in class B. Note that we have called the method on an object that is actually a B, so the arik method in B is called, which prints Arik_B.

Upvotes: 5

bobbel
bobbel

Reputation: 3357

Because with the class B you are overwriting the method arik, so that's why it's accessing this method in class B.

And your ab variable is still a B.

Upvotes: 0

Related Questions