0

As per Oracle Tutorials

A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.

[Question] For a class relationship as Sub extends Super, It's understood that The Oracle docs say so just to support the fact "only inherited methods can be overridden" but then it is kind of misleading statement, as if it seems to imply => if a method is not inherited then it is not present as a behavior of the object of Sub class and if so then it can in no way be invoked on an object of Sub class. But a method in class Super can invoke the private method defined by Class Super on an Object of Sub class. Please refer below points and related code and suggest if there some gap in my understanding ?

I have always understood the inheritance as below 3 points

  1. A class Sub inherits all instance methods and fields (including the private).
  2. If a method is private in Super then it is not visible in Sub but this does not mean that an object of Sub does not have the behavior.

Code for point 1 and 2

public class Super{
    private void privateMethod(){
        System.out.println("private method defined in Super");
    }
    public void m(){
        privateMethod();
    }
}

public class Sub extends Super{

} 
public void Other{
    public static void main(String[] args){
        Sub s = new Sub();
        s.m(); 
    }
}

We have created an object of Sub, m() is inherited by Sub and its public meaning it can be accessed by code outside Super. On invoking m() we are able to invoke privateMethod(). If private methods were not inherited then some run time exception would have occurred which is not the case.

  1. Overriding is applicable to visible instance methods in Sub class only. If a method is not visible an is defined in both classes, Sub and Super, then the object has both the capabilities and both the methods can be invoked by the code which can access the particular method ( refer code below)

Code for point 3

public class Super{
    private void privateMethod(){
        System.out.println("private method defined in Super");
    }
    public void m(){
        privateMethod();
    }
}

public class Sub extends Super{
    private void privateMethod(){
        System.out.println("private method defined in Sub");
    }
    public void m2(){
        privateMethod();
    }
} 
public class Other{
    public static void main(String[] args){
        Sub s = new Sub();
        s.m(); // m() will invoke private method of Super
        s.m2(); // m2() will invoke private method of Sub
    }
}

Saying that Sub class does not inherits private method from Super implies method can not be invoked on an object of Sub as the behavior is not inherited, hence not part of ( does not belongs to) the object. Above we see it is not the case.

JJJ
  • 32,902
  • 20
  • 89
  • 102
nits.kk
  • 5,204
  • 4
  • 33
  • 55
  • You may want to change the output of the `Sub` class method. Remove the methods and it's not available for `Sub` instances, and you can't call either from `Other` directly, which is what's meant. – daniu May 06 '19 at 17:55
  • @daniu Please elaborate what method you are referring to, I have edited the question for better understanding. – nits.kk May 06 '19 at 18:00

2 Answers2

1

I think the key difference is in how the Java Language Specification uses the term "inherit". (Note that the JLS is the authoritative documentation, not the Java tutorials.)

JLS 8.2, Class Members says:

Members of a class that are declared private are not inherited by subclasses of that class.

But, when describing the behavior of the new operator, JLS 15.9.4, Run-Time Evaluation of Class Instance Creation Expressions says (emphasis mine):

The new object contains new instances of all the fields declared in the specified class type and all its superclasses.

This means that the superclass fields are not inherited by the subclass, but an instance object of the subclass still contains those fields. The same concept applies to private methods as well.

Although a private method from a superclass can be called on an instance of a subclass, the method is not formally a part of that subclass. The private method still belongs to the superclass.

This works because of the subtyping ("is-a") relationship. An instance of the subtype is an instance of the supertype. The class does not inherit those members into itself, but an instance of the class still contains them.

Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135
  • thanks, the first edit I did after reading to your answer : corrected the mistake : calling the quoted statement as oracle docs and not oracle tutorial. Also I feel its better to use word contains ( an object of sub contains the method which are private in super class, in case both classes have same method then it contains both of them and method will be invoked as per the calling code). – nits.kk May 06 '19 at 19:17
0

In the example you've given, privateMethod from class Super is indeed private and cannot be inherited by Sub. Such design implies that we don't want subclasses to be able to have privateMethod behavior, that's why it is illogical to wrap privateMethod in a public method, which the Sub class can then execute and have the "private behavior". So this implementation wouldn't be used in real life.

And since privateMethod is not inherited by Sub, the privateMethod implemented in it is not an override, but rather a method that happens to have the same signature. If you hadn't defined the method in Sub, you wouldn't be able to use s.m2() (which is s.privateMethod()).

But a method in class Super can invoke the private method defined by Class Super

And that's what it's meant to be: any class can use a method defined in itself, be it public or private.

Ety
  • 334
  • 5
  • 13
  • Actually its the reverse what you say. If private methods are not wrapped in any non public method then private method is not of much use. Its the public methods which defines the contract of the class with the dependent or user classes and the internal implementation is done in private methods. you can refer to 'ensureCapacity' its Public method in java.util.ArrayList and it uses the private grow() method. This is just one such example – nits.kk May 06 '19 at 18:16
  • @Ety Always a private method has to be part of the method calls starting from the invocation of a public method or public constructor in order to be useful. Refer to the `ensureCapacity' its Public method in java.util.ArrayList and it uses the private grow() method. (I commented because you said illogical to wrap privateMethod in a public method...) – nits.kk May 06 '19 at 19:48
  • @Daniel Pryden I have deleted that comment and have re phrased it – nits.kk May 06 '19 at 20:19