Reputation: 35
I have these classes:
class A {
public void f() { System.out.println("f() in A"); }
public void g() { System.out.println("g() in A"); f(); }
}
class B extends A {
public void f() { System.out.println("f() in B"); }
}
Why does
B b = new B();
A a = b;
a.g();
print out this
g() in A
f() in B
and not
g() in A
f() in A
Is there something I am missing?
Upvotes: 3
Views: 123
Reputation: 38910
Now you got idea about polymorphism and overriding.
Since you did not get your expected output, I would suggest a way to get your expected output through method shadowing or hiding
If you re-define base class non-static & non-private method in derived class, it's called overriding.
In this example, A holds the instance of B and hence f()
has been invoked from B instead of A.
If you re-define base class static method/variable is derived class, it's called hiding or shadowing.
In above example, just add static
modified for g()
method and you will get required output. Now g()
method
class A {
public static int i=10;
public static void f() {
System.out.println("f() in A:i="+i);
}
public void g() { System.out.println("g() in A"); f(); }
}
class B extends A {
public static int i=20;
public static void f() {
System.out.println("f() in B:i"+i);
}
}
public class Test2 {
public static void main(String args[]){
B b = new B();
A a = b;
a.g();
}
}
output:
g() in A
f() in A:i=10
Upvotes: 0
Reputation: 133587
This is because Java uses dynamic dispatch by default (and forcibly) on methods of classes.
This feature makes sure that, when a method is called, the most specialized version of it it is chosen to be executed. In your case, since B extends A
, it means that public void f()
implementation of B
is more specialized than the one of A
. So although A a
is statically of type A
, it's dynamically of type B
and that method is chosen.
Upvotes: 3
Reputation: 458
The reference variable type of an object determines which methods are accessible.
The class of an object determines which methods exist. These methods that exist but are not accessible can be accessed through casting.
i.e: ((B) a).g();
Will allow you to access the B
version of G. This only works because underneath a
is a B
.
Upvotes: 0
Reputation: 808
https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
This is called polymorphism. It lets us do things like hold a list of type Animal, but when we put a cat in it, and do animal.performcall() it will print a meow. This is the example my teacher gave me many years ago, anyway :)
Upvotes: 1
Reputation: 2566
Yes, even though variable "a" is of type A, the object reference it holds is of type B, so f() in B is what's called.
Upvotes: 2