Java Inheritance and Method Overloading

I 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 will be "3".

Can anyone explain in more detail the theoretical concept of this result.

I know that class A is abstract and why it is impossible to create it, but I would like to understand the whole mechanism of this result.

+7
java inheritance method-overriding method-overloading
source share
5 answers

The overloaded method is selected at compile time. Since your code calls met((A) this) , the method signature with an argument of type A is selected.

Now, at run time, the JVM must decide which met(A a) method to execute. This is determined by the runtime type of the object for which the method is being 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.

+5
source share

Method signatures are determined at compile time.

 .met(A) 

must be called because the signature does not change depending on the actual type of the object, only the type is represented.

However, polymorphism is used to determine which implementation of this signature is called.

The this object is C , which extends B , and therefore the implementation in B is the one that is called.

This is why B.met(A) called.

+1
source share

B is the only class that implements A, so implementations of A will never be executed as B, since they redefined them.

When you put your C object as A, it is still a C object, so the call that occurs on this object will be executed by method B. This call is resolved at run time using the real type of the object.

As for the parameter, you selected it as A, so the java compiler pointed to the correct method: B.met (A)

+1
source share
 return ((A) this).met((A) this); 

When you write this , it always points to the current instance, which is C , which extends B , and you did not overload the method, so it pointed to the superclass method ( B ).

And, having come to part (A) this , it still points only to this , and not to A The main implementation of the methods is still the same. You just change the type.

+1
source share

((A) this) .met ( (A) this ) is interpreted as - instanceOfC .met ( typeOfA )

two questions arise why

  • class selected as B not A - subclass over superclass
  • in class B, met is selected as met (A) does not occur (C) or occurs (B) - type over instance

A. Overriding - a subclass over a superclass

  • if the same method signature in the subclass of the object ,

  • then he was selected from a subclass.

  • so ((A) this) .met resolver for instanceOfC.met

B. Overload - Instance Type

  • if a repeating method name is found in the class,
  • Then the selected one was the same parameter as the argument,
  • therefore, met ((A) instanceOfC) , interpreted as met ( typeOfArgument )

So

  • this.met ((A) null) will also call B.met (A)
  • this.met (this) will call B.met (C)
  • if we remove B.met (C), this.met (this) is called A.met (C) , that is, overriding does not occur.
  • and then removing A.met (C), it will call B.met (B) , - it overloads the closest type < .
+1
source share

All Articles