user1150082
user1150082

Reputation: 67

private scope and inheritance in java

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

Answers (4)

Stephen C
Stephen C

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

tucuxi
tucuxi

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

balbusm
balbusm

Reputation: 1734

Field 'a' is inherited. It is not directly accessible from class B. Only class A can access field a.

Upvotes: 2

Bathsheba
Bathsheba

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

Related Questions