Reputation: 93
I have problems understanding the behaviour of this piece of code. a is defined as an A, c is defined as a C. Then, at the end of the public class, a = c. When a calls the display() method it reaches the C version of it. But when a calls the f() it only reaches the A version, despite the fact that the first arguments (byte and long) are more compliant with long than float.
It's an exercice from a book, but explanation is scarce, or inexistent.
class A{
public void display(){
System.out.println("I am an A ");
}
public void f(double x){
System.out.println("A.f(double = " + x + ") ");
}
}
class C extends A{
public void display(){
System.out.println("I am a C ");}
public void f(long q){
System.out.println("C.f(long = " + q + ") ");}
}
public class PolySurStack{
public static void main(String Args[]){
byte bb =1; long q = 4; float x = 5.f;
System.out.println(" ** A **");
A a = new A(); a.display();
a.f(bb); a.f(x);
System.out.println();
System.out.println(" ** C **");
C c = new C(); c.display();
c.f(bb); c.f(q); c.f(x);
System.out.println();
a = c; a.display();
a.f(bb); a.f(q); a.f(x);
}
}
Upvotes: 1
Views: 103
Reputation: 93
I just found this on another forum :
Overloading :(same function name but different signature)
Two or more methods having the same name with different arugment in same class is known as Overloading.
Overloading is used when you want to extend the functionality.
Overloading is known as compile time polymorphism
Overriding :(same function name but same signature)
Two or more methods having the same method name and same arugment in parent class and child class in known as overriding.
Overriding is used when you want to reuse the existing functionlity.
Overriding is known as run time polymorphism
So the answer to my question seems to be that overriding resolution (like for display() )occurs at run time (here after a = c) while overloading resolution (like for f() ) occurs at compilation time, when a is Still an A.
I think.
I also found this page : https://beginnersbook.com/2013/04/runtime-compile-time-polymorphism/
to be clear and highly relevant to this topic.
Upvotes: 1
Reputation: 2239
I'll try to clarify the answer of @eran a bit so you can understand it.
A subclass has all the methods of its superclass, and then perhaps some more in addition to them. You have a variable of type A
, in which you store an object of type C
. C
has all the methods that are defined in class A
, and also an additional method that is f(long q)
. A
is unaware of this new method, so since you store the object in a variable of A
, you can't call f(long q)
.
You can however call display()
because it is defined in A
, but it will still be the C
object that executes it.
Upvotes: 0
Reputation: 131326
The method selected by the compiler depends on the declared type, not on the runtime type.
The first series that declares as variable A
can only invoke A methods (whatever the runtime type instantiated as A
derives only of Object
) :
A a = new A();
a.f(bb); a.f(x);
For the second series, the compiler binds the methods with the most specific parameter matching to the invocation since C
is a A
and so the compiler can bind any public methods of these here :
C c = new C();
c.f(bb); c.f(q); c.f(x);
But in the last chunk of code that probably questions yourself, a
refers to C
as runtime object but to A
as declared type :
A a = new A();
// ...
a = c;
a.f(bb); a.f(q); a.f(x);
So only methods defined in A
may be invoked.
Upvotes: 0
Reputation: 393771
When you call a.f(bb)
or a.f(q)
or a.f(x)
, the only method signatures the compiler can choose from are those defined in class A
(or any super class of A
), since a
is a reference variable of type A
.
Therefore, only public void f(double x)
is considered. In order for public void f(long q)
to be a candidate for overload resolution, you'd have to cast a
to type C
before calling f()
, since only class C
defines a method with that signature.
The important thing to understand is that method overloading resolution takes place in compile time. Only the compile time type of the reference variable for which you call the method determines which method signatures are candidates for method overloading resolution, as well as which candidate will be chosen.
Upvotes: 1