11

Here's an interesting code snippet:

public class Superclass {

    public static void main (String[] args){
        Superclass obj = new Subclass();
        obj.doSomething(); #prints "from Superclass"
    }

    private void doSomething(){System.out.println("from Superclass");}
}

class Subclass extends Superclass {

    private void doSomething(){System.out.println("from Subclass");}

}

I know that subclasses do not inherit the private members of its parent, but here obj manages to call a method to which it should have no access. At compile time obj is of type Superclass, at runtime of type Subclass.

This probably has something to do with the fact that the call to doSomething() is taking place inside the driver class, which happens to be its own class (and why it's possible to invoke doSomething() in the first place).

So the question boils down to, how does obj have access to a private member of its parent?

Victor Cheung
  • 153
  • 1
  • 1
  • 4
  • It would be interesting see what happens when the child method is public. I have done it, it says: "from Superclass" Interesting, it does not overRide it – David Marciel Dec 14 '16 at 15:39

9 Answers9

18

Private methods are only for the owner.

Not even for the kids, relatives or friends of the owner.

Alex Kreutznaer
  • 1,170
  • 8
  • 18
15

You answered it yourself. As the private methods are not inherited, a superclass reference calls its own private method.

Swapnil
  • 8,201
  • 4
  • 38
  • 57
  • If by "reference" you mean the instance of Subclass referenced by the pointer stored in variable obj, it's a circular answer. That instance is still of type Subclass, and it should not have access to the parent's private member. – Victor Cheung Jan 18 '13 at 03:50
  • 4
    The point is that you're assigning it to a superclass reference. And with that method being private, it's not going to be overridden by subclass implementation. That reference knows about only one doSomething method, which is in the superclass. – Swapnil Jan 18 '13 at 03:52
5

It works because you are casting to a Superclass from within a method of the Superclass. In that context, Superclass.doSomething is available to the compiler.

If you were to change your super and subclasses to two different arbitrary classes A and B, not related to the class containing the main method, and try the same code, the compiler would complain about not having access to the method.

5
Superclass obj = new Subclass();

At this point, obj is both things, a Subclass, and a Superclass object. The fact that you use Superclass in the declaration of the variable is just a matter of casting it.

When you do: obj.doSomething(), you are telling the compiler to call the private method doSomething() of obj. Because you are doing it from the main static method inside Superclass, the compiler can call it.

If you would use the main method of Subclass rather than the one in Superclass, you would not be able to access that method because, as you said, it's neither inherited nor a part of your definition of Subclass.

So basically you understood inheritance correctly. The problem was related to the visibility of private methods.

O.Badr
  • 2,853
  • 2
  • 27
  • 36
Pauls
  • 2,596
  • 19
  • 19
3

When you used this line:

Superclass obj = new Subclass();

You casted Subclass into a Superclass Object, which uses only the methods of the Superclass and the same data. If you casted it back into a Subclass, you could use the Subclass methods again, like so:

((Subclass)obj).doSomething(); #prints "from Subclass"
EAKAE
  • 153
  • 1
  • 11
  • 1
    Given the OP code, `((Subclass)obj).doSomething(); #prints "from Subclass" ` won't compile, as you're accessing a **private** method outside of its class `Subclass`. – O.Badr Dec 31 '17 at 19:49
3

Since the reference type of the object obj is SuperClass, a call to doSomething() tries to access the private method defined in SuperClass itself (private methods cannot be overridden). As doSomething() is accessible within SuperClass, the main method can call doSomething() without giving any error/s.

Hope this helps! :-)

learner
  • 29
  • 3
1

why it's possible to invoke doSomething() in the first place?

Why not? obj is an instance both of Subclass and Superclass, and as doSomething() is declared in Superclass and obj is used in it, so you've access to Superclass.doSomething(), you may try to rename your method (to e.g.: doAnotherThing()) and you'll still have access to it.

how does obj have access to a private member of its parent?

There is no parent/child for a private method, and as obj is also a type of Superclass, so it has access to all private methods/fields declared within it, because obj is used in this class. You will lose this access privilege if you're outside of Superclass or of a class that has Superclass as a member (nested class).

So What?

There is no relation/inheritance between SuperClass's private methods and SubClass's private methods, even they have the same name and signature, from Java Language Specification, Java SE 8 Edition:

A private method and all methods declared immediately within a final class (§8.1.1.2) behave as if they are final, since it is impossible to override them.

O.Badr
  • 2,853
  • 2
  • 27
  • 36
0

To understand this question you can relate private method to member variable of super class and sub class.

So we know member variable is not going to be overridden in sub class.

For example:

Class A{
 int i = 10;
}

Class B extends A{
  int i = 11;
}

Class C extends A {
   int i = 12;
}

A a1 = new B();
print(a1.i) // Will print 10

A a2 = new B();
print(a2.i) // Will print 10 

Similar way when there is no inheritance reference variable super class is going to be considered.

-1

When we define a private method with the same name in the derived class, it becomes a new method as derived class don't inherit the private members.

Since the private method is not even visible outside the class, we can never call a base class private method from a derived class, it will throw a compilation error:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method aPrivateMethod() from the type Base is not visible

We can use down casting to the parent class reference to call the derived class private method, which can only be accessed in that derived class.