Why do child classes apply the default parent type to the parent version of private instance methods, but not to other instance methods?

It was my understanding that a child dropped by the parent type (as in Super sc = new Child(); ) will call the static methods of the parent class and access the non-hidden fields of the parent class, but will use the instance methods of the child class.

This is not like the case of private instance methods (those in which overriding does not actually occur because the parent method is private.)

I understand that the fact that there is no override (private parent methods are not visible to the child, so they can be hidden.) Would mean that the child would not look for a hierarchy to see the parent version of the method when the instance method is called from the child.
However, the exact opposite of what I expect is happening (the version present in the called child). The parent version of the private method is called.

Why does this happen if the instance methods of the child are usually called, and inside the child there is a method with an identical signature (in this case, this is the perfect match for calling method2() ) that hides the same method in the parent class?

 package whatever; public class A { public void method1(){ System.out.println("A method1()."); } //using "final" here to emphasize that this is a hiding, not an override. private final void method2(){ System.out.println("A private method2()."); } public static void main(String[] args) { A a = new A().new B(); a.method1(); //calls B method 1 ((AB)a).method1(); //calls B method 1 a.method2(); //calls A private method 2 **I expected it to call B private method 2 ((AB)a).method2(); //calls B private method 2 } public class B extends A { public void method1(){ System.out.println("B method1()."); } private final void method2(){ System.out.println("B private method2()."); } } } 
+5
source share
3 answers

First, B is actually a nested class, and, oddly enough, private members of nested classes can access the outer class. Otherwise, it would be even legal to do ((AB)a).method2(); (the converse is also true. B can also access private members in A.)

However, to answer your real question, the reason why a.method2(); calls the private method in A, lies in the fact that private methods are not virtual, because they cannot be overridden at all. (How can they be if class inheritance doesn't even have to know about them?) Thus, they are bound at compile time, which means using a declared variable type. A a declared as A, but (AB)a is executed when compiling to B. Thus, your first call uses the private method from A, and your second call uses the private method from B.

It is bizarre that the facts in these two paragraphs do not interact with each other. One would expect that since the nested class “knows” about the outer members of the outer class, redefinition may be possible. But this is not so. Private functions are never displayed in vTable and can never be overridden.

+2
source

Short answer: because your B class is in the same file (.java) with the one that contains the #main() method.

0
source

The reason the private method of the parent class is visible to the child class is because the child class is an inner class of its parent class in your case.

Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private

0
source

Source: https://habr.com/ru/post/1202409/


All Articles