Good day to all.

I just started to prepare for an interview on the Java Junior , as there was a slight misunderstanding about polymorphism . I studied Java Core from the book by Kathy Sierra and Burt Bates ("Learning Java. 2nd Edition") .

There, the inheritance mechanism (and generally the storage of objects in the JVM heap ) was presented like this:

public class A{ //code... } public class B extends A{ //code... } public class TestApp{ public void init(){ B val = new B(); } } 

And in the JVM, it all looks like this:

enter image description here

Suppose we have this code:

 public class Animal{ public void makeSomthing(){ System.out.println("Animal"); } } public class Dog extends Animal{ //переопределенный метод @Override public void makeSomthing(){ System.out.println("Dog"); } public void fMagic(){ this.makeSomthing(); //Console: Dog super.makeSomthing(); //Console: Animal [?] } } public class TestApp{ public static void main(String[] args){ Dog dogPet = new Dog(); dogPet.fMagic(); } } 

It turns out that when you call the fMagic() method, the fMagic() object also calls the makeSomthing() method on the "external" Dog object and also the same method on the "internal" Animal object (on the superclass). As I understand it, according to the logic of this book, the construction of the override ( @Override ) of methods is that the method is essentially one, and when we redefine it, we change it in the "internal" object using the "external" . And already when calling dogPet.fMagic() it is called from within.

enter image description here

But at the same time:

Dog class

  public void fMagic(){ this.makeSomthing(); //Console: Dog super.makeSomthing(); //Console: Animal [?] //Console: Dog@74a14482 - адрес Dog. Dog@74a14482 - адрес Animal. System.out.println("links:"+"\n" + this + " - адрес Dog. "+ super.getObjectLink() + " - адрес Animal."); } 

Animal class

  public Object getObjectLink(){ return this; } 

But the strangest thing in my opinion is this: When narrowing the type to its parent, the call to the function is given by "Dog", not "Animal". That is, in this case, overriding a method in the class Dog changes the method saySomthing() . But in the case of calling the fMagic() method of the Dog class, 2 different functions are called. And the redefinition of the function of the superclass, as I understand it, gives nothing.

  Animal dogPet = new Dog(); dogPet.makeSomthing(); //Console: Dog 

The essence of the question: How exactly do all these processes and mechanisms of the PLO actually occur? And why, when calling fMagic() two different "Dog" and "Animal" inscriptions are displayed on the console, and not the same "Dog" inscription, as in the case of Animal dogPet = new Dog(); ?

  • Virtual function table? I'm talking about the last question why 2 different inscriptions. Rti or something like that - pavel
  • @pavel I apologize, I did not quite understand you. - SlandShow
  • In c ++, the method of the Animal object would be called, and 'Animal' would be printed. If only the method was not declared virtual, and then everything would be exactly the same. In java, all methods are virtual, always. - Wyvie
  • Animal dogPet = new Dog(); dogPet.makeSomthing(); //Console: Dog Animal dogPet = new Dog(); dogPet.makeSomthing(); //Console: Dog And dogPet.fMagic(); - and will display a message of both the class itself and its superclass. Nothing strange. - DimXenon
  • Those. what else to expect from calling the superclass method? You redefine the behavior in your (!) New heir class. A parent and a descendant behave like living beings: if a descendant is not taught in a new way, it acts like a parent. But if a descendant is taught to do something in a new way, this will not force the parent to change behavior. - DimXenon

1 answer 1

First, tie in with such terminology, there are no external and internal objects. You have a Dog class that extends the Animal class. Inheritance is a type relation is (is a). Therefore, in your case, the Dog object is an Animal object, which means it contains its behavior. The behavior of the parent class can be used in a subclass with the super keyword, which you have demonstrated.

The keyword this used to get the object to link to itself, which in this case is done by default. Those. You will get the same result if you omit it.

To better understand the benefits of polymorphism, consider the Strategy design pattern. In my opinion one of the most vivid examples.

Also if you write Animal dog = new Dog(); You say to the machine: "Create me a Dog object and place it in a variable of type Animal ." You can do this because Dog is an Animal . However, referring to this variable, you will call the class method Dog because it contains a Dog object. Animal here is the type of the variable, not the object.