Reputation: 153
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?
Upvotes: 11
Views: 35669
Reputation: 2636
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.
Upvotes: 5
Reputation: 3121
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.
Upvotes: 1
Reputation: 1
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.
Upvotes: 0
Reputation: 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.
Upvotes: -1
Reputation: 29
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! :-)
Upvotes: 3
Reputation: 1336
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.
Upvotes: 5
Reputation: 1170
Private methods are only for the owner.
Not even for the kids, relatives or friends of the owner.
Upvotes: 18
Reputation: 153
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"
Upvotes: 3
Reputation: 8318
You answered it yourself. As the private methods are not inherited, a superclass reference calls its own private method.
Upvotes: 15