Reputation: 67
Consider this simple java code :
class A {
private int a = 10;
public void print() {
System.out.println(this.getClass().getName() + " " + a);
}
}
public class B extends A {
public void p1() {
print();
}
public static void main(String... args) {
B b = new B();
b.p1();
}
}
If you will run the code , the value that gets printed is B 10 . My question is if "a" is not inherited when we use "private" modifier but the method is , then there is method print() in class B now but "a" is not part of the class since it is private, so how is it that the compiler doesn't throw error when we try to access it by saying scope of "a " is private ?
Upvotes: 3
Views: 725
Reputation: 719561
The JLS (8.3. Field Declarations) states this:
A class inherits from its direct superclass and direct superinterfaces all the non-private fields of the superclass and superinterfaces that are both accessible to code in the class and not hidden by a declaration in the class.
A private field of a superclass might be accessible to a subclass - for example, if both classes are members of the same class. Nevertheless, a private field is never inherited by a subclass.
But, what does "inherit" actually mean?
What it actually means is that the name of the (inherited) method or field is present in the namespace of the subclass. A private
method is not present. It cannot be named in the namespace of the subclass.
On the other hand, the private field of a superclass must be present in an instance of the subclass. If it wasn't present, then methods declared in the superclass that use the private field could not function.
But then we have the bit about nested classes; e.g.
public class Outer {
class A {
private int a;
...
}
class B extends A {
private int b1 = a; // Compilation error
// field 'a' is still accessible!
private int b2 = ((A this).a; // OK!
}
}
(Yes ... really!!)
The interesting thing though is that the compilation error you get for the above is:
Test.java:7: error: a has private access in Test.A
private int b = a;
The compiler writers have decided to describe this situation as access to a private variable, not as access to a variable that has not been inherited.
My question is if "a" is not inherited when we use "private" modifier but the method is , then there is method print() in class B now
... yes ...
but "a" is not part of the class since it is private,
No!
That's not what inherit means for a field. The field a
is present in every instance of B
. It is just that it is not accessible. You can't name it.
so how is it that the compiler doesn't throw error when we try to access it by saying scope of "a " is private ?
Because it is there.
Opinion: the Java definition of "inherited" with respect to private
fields and methods is confusing. Even counter-intuitive. However, it is what it is.
Upvotes: 1
Reputation: 17955
You are confusing inheritance with visibility/access.
The a
attribute is not visible/accessible directly from within B
; but it is definitely inherited, in the sense that it is still there, because an instance of B
contains an instance of A
(class B extends A
), and that instance of A
(where the print()
method lives) always contains that a
attribute.
Upvotes: 0
Reputation: 1734
Field 'a' is inherited. It is not directly accessible from class B. Only class A can access field a.
Upvotes: 2
Reputation: 234875
print
in class A
is reachable in class B
as it's public
and class B
is a child of class A
.
But print
in class A
can see all the fields in class A
since it's a method of that class. So that function can see a
, and hence compilation passes.
Upvotes: 3