I've tried to execute the following code:
abstract class A {
int met(A a) { return 0;}
int met(B b) { return 1;}
int met(C c) { return 2;}
}
class B extends A {
int met(A a) { return 3;}
int met(B b) { return 4;}
int met(C c) { return 5;}
}
class C extends B {
int fun() {
return ((A) this).met((A) this);
}
}
class Test {
public static void main(String[] args) {
C x = new C();
System.out.println(x.fun());
}
}
And the output is "3".
Can someone explain in more detail the theoretical concept behind this result.
I know that class A is abstract and that's why it cannot be instantiated but I'd like to understand the whole mechanism of this result.
Yes of course, overloading in inheritance class is possible in Java. Java compiler detect that add method has multiple implementations. so according to the parameter java compiler will determines which method has to be executed. class Parent { public void add(int a) { System.
Overloading allows several function definitions for the same name, distinguished primarily through different argument types; it is typically resolved at compile-time. Inheritance allows subclasses to define more special versions of the same function; it is typically resolved at run-time.
Note: In a subclass, you can overload the methods inherited from the superclass.
Inheritance is a mechanism in which one object acquires all the properties and behaviours of parent object. Inheritance represents the IS-A relationship. If subclass (child class) has the same method as declared in the parent class, it is known as method overriding.
The overloaded method is selected at compile time. Since your code calls met((A) this)
, the method signature with the argument of type A
is chosen.
Now, at run time, the JVM has to decide which met(A a)
method to execute. This is determined by the runtime type of the object for which the method is called. Since your object is of type C which extends B, met(A a)
of B
(which overrides met(A a)
of A
) is executed.
Method signatures are determined at compile time.
.met(A)
must be called as the signature doesn't change based on the actual type of the object, only the type is appears to be.
However, polymorphism does apply to determine which implementation of this signature is called.
The object this
is a C
which extends B
and so the implementation in B
is the one called.
This is why B.met(A)
is called.
B is the only class implementing A so A implementations will never be executed as B as overrided them.
When you cast your C object as A, it's still a C object so calling met on this object will execute the method of B. This call is resolved at runtime using the real type of the object.
Concerning the parameter, you casted it as a A so the java compiler made it point to the right method : B.met(A)
return ((A) this).met((A) this);
When you write this
it's always points to current instance which is C
which extends B
, and you didn't over-ridden the method hence it's pointing to the method of super class (B
).
And coming to the part (A) this
, it still points to this
only, not the A
. The underlying implementation of methods still remains same. You are just changing type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With