java – Can't understand polymorphic method call

Question:

I have a Pair class:

public class Pair {
   public void getObject(Object o){
       System.out.println("Text from Pair");}
 }

The Detail class inherits from it, which has the same method, but it accepts an object of a different type:

public class Detail extends Pair {
  public void getObject(Date o){
    System.out.println("Text from Detail");}
}

In Main I have this:

Detail d = new Detail();
Pair p = d;
p.getObject(new Date());

And in fact, a polymorphic method call should be executed, but for the Detail object, the getObject method from the Pair class is called, why is this? How exactly does a method call work here?

Answer:

There are 3 behaviors in java that are relevant to your theme:

  • overriding (official documentation here )
  • overloading (official documentation here – section "Overloading Methods")
  • hiding (official documentation here )

Since the documentation says that:

The overriding method has the same name, number and type of parameters, and return type as the method that it overrides. An overriding method can also return a subtype of the type returned by the overridden method. This subtype is called a covariant return type.

and in your case you have violated the rule number and type of parameters , then it turns out it's not override. At the same time, the following is written regarding overload:

The Java programming language supports overloading methods, and Java can distinguish between methods with different method signatures. This means that methods within a class can have the same name if they have different parameter lists (there are some qualifications to this that will be discussed in the lesson titled "Interfaces and Inheritance").

Which applies specifically to your situation. Thus, by calling the method by reference Pair p you will call the method of the Pair class, despite the fact that it is actually a Detail object.

In addition, java has a mechanism for tracking such misunderstandings in the form of @Override annotation, marking the method with it the compiler will @Override error if it is not override. In your case:

@Override
public void getObject(Date o){
    System.out.println("Text from Detail");}

The compiler will give an error "Method doesn't override method from its superclass" .

Finally, to achieve a real overrid in the Detail class, the method should look like this:

public void getObject(Object o){
    System.out.println("Text from Detail");}

In this case, you will receive the expected result.

I hope I managed to explain everything in detail. Good luck with further study =).

Scroll to Top