Reputation: 265
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
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:
new B();
and call B.superYosef();
super.yosef();
appearing in that method invokes A.yosef()
statically (not subject to dynamic dispatch);A.yosef()
calls this.arik()
—unlike above, a method called on this
is subject to dynamic dispatch;this
is B
, therefore the method B.yosef()
is called.Upvotes: 5
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
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
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