I have a Pair class:

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

The class Detail inherited 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, the polymorphic method call should be executed, but for the Detail object, the getObject method is getObject from the Pair class, why is that? How exactly does the method call work here?

  • 2
    here you have a completely different method, because the signature is different ....... polymorphic, if the signature were the same - Alexey Shimansky

3 answers 3

In java, there are 3 behaviors related to your topic:

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

Since the documentation states that:

This is a list of the parameters of the parameters. An overriding method can be returned. This subtype is a covariant return type.

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

The Java programming language supports the different methods of Java. If you have different parameter lists, you can find out what you’re talking about.

What exactly relates to your situation. Thus, calling the method by the Pair p link you will call the Pair class method, despite the fact that this is actually a Detail object.

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

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

The compiler will generate the error "Method doesn't override method from its superclass" .

Well, in the end, in order to achieve true overrid in the class Detail method should look like this:

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

In this case, you will get the expected result.

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

    In order for a derived class function to be considered a polymorphic variant of the base class function, they must have not only the names, but also the types of arguments to match. In your case, the two functions are considered just an overload of the name getObject . And in p.getObject(new Date()); there is a call to the class Pair .

    similar question

    • one
      The question was why. - Qwertiy
    • one
      @Qwertiy there is no such question there) - Alexey Shimansky

    To understand what is happening, you need to clarify a few concepts:

    1. Reloading You can have 2 methods in the same class with the same name but different parameters.

    2. Override A complete match of the input parameter types is required.

    3. Inheritance. Provides fields and methods of the parent class.

    These are not definitions of concepts of overload, redefinition and inheritance, but only some of the points relevant to the issue.

    In your case, the Detail object has two variants of the getObject method, one that you explicitly defined directly in the class: public void getObject(Date o) , and the second that it received from the parent as a result of inheritance: public void getObject(Object o) .

    When the VM needs to determine which method to call, it looks at what type of parameter you sent to the method, and according to the type of this parameter it selects the appropriate overload option.

    Following this logic, you might think that a method with a parameter of type Date should be called. But you do the casting :

     Detail d = new Detail(); Pair p = d; //Вот здесь. Это равнозначно Pair p = (Pair) d; p.getObject(new Date()); 

    A list of methods for an object is always determined by the type of pointer . And since the pointer type is now Pair and he has only one version of this method, he volunteered. Well, since it accepts Object then the Date “swallowed without frowning.” And the only method available for Pair getObject(Object) .

    • one
      That's not quite. If in this example you put Date as an input parameter for Pair or Object then "Text from Detail" will appear, and not "Text from Pair" spite of all these types of pointers ....... for the sake of interest, put Date in Pair and Object in Detail - the result will be the same as that of the vehicle, although, according to your logic, it was also influenced by the fact that Object swallowed the Date - Alexey Shimansky
    • @ Alexey Shimansky, no, you misunderstood my explanation. The fact that Object has swallowed Date means that there are no problems with type casting. And my logic indicates that the list of methods is determined by the type of pointer, and in the case of overloading of parent methods, this is also true. - Pavel