3

I have three classes:

package pac;

public class A {
    protected A a;  
    protected final int i = 10;
}

public class B extends A {

    void foo() {
        A a = new A();
        int b = a.a.i;  //compiles fine
    }
}

package another.pac;

public class C extends A {

    void foo() {
        A a = new A();
        int b = a.a.i;  //Does not compile. a.a is inaccessible
    }
}

Why can't we access a protected member from a put into another package, but from the same package we can? They both are subclasses of one, therefore acces should have been permitted.

JLS 6.6.2.1 says:

If the access is by a field access expression E.Id, or a method invocation expression E.Id(...), or a method reference expression E :: Id, where E is a Primary expression (§15.8), then the access is permitted if and only if the type of E is S or a subclass of S.

The class C satisifies the requerement. What's wrong?

stella
  • 2,546
  • 2
  • 18
  • 33
  • 1
    That's the idea of protected, that only classes in the same package can access it... Otherwise make it public – Danielson Jun 25 '15 at 12:54
  • 2
    @Danielson *That's the idea of protected, that only classes in the same package can access it... Otherwise make it public*. Not true. – Chetan Kinger Jun 25 '15 at 12:58
  • @ChetanKinger good explanation... The non-packaged class cannot directly access the field... It can through inheritance, but then you are calling a class inside the package – Danielson Jun 25 '15 at 13:04
  • @Danielson *but then you are calling a class inside the package*. Not sure what you mean. Can you elaborate? – Chetan Kinger Jun 25 '15 at 13:05

3 Answers3

4

A protected member can be accessed in a subclass outside the package only through inheritance. Try this instead :

public class C extends A {

    void foo() {
       int b = i;  
    }
}
Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82
  • 2
    Yes, I just don't see how it answers my question. I believe that you just didn't understand what I was looking for. I've made it clear now. – stella Jun 25 '15 at 13:10
  • @stella You just made an edit quoting the JLS which was not a part of your quesiton when I posted the answer. My answer did answer your question before you edited it. Even after your edit, my answer still explains the golden rule for `protected` members. What part of *A protected member can be accessed in a subclass outside the package only through inheritance* did you not understand? Don't downvote answers because of a lack of understanding on your part. – Chetan Kinger Jun 25 '15 at 13:12
  • No, now I got the rules. It's clear. – stella Jun 25 '15 at 13:17
2

There are no needs to make a reference every time. I think you didn't understand Inheritence..

public class B extends A {

    void foo() {
       // A a = new A(); No need to instantiate it here as B extends A
        int b = i;  //No nedd to refer it through a.a.i  
    }
}

package another.pac;

public class C extends A {

    void foo() {
        C c=new C();
        int d=c.i//this will work fine
       //   A a = new A(); same as above explanation
        int b = i;  //same as above and even a.i will not compile
    }
}

Now Your protected variable will be accessible here..

Hiren
  • 1,427
  • 1
  • 18
  • 35
1

Class A is apart of package pac;

and Class C is apart of package another.pac therefore it will be unable to access its member. If C is apart of package pac then it would be able to access the member

See the following post: In Java, difference between default, public, protected, and private

Community
  • 1
  • 1
mstelz
  • 610
  • 4
  • 9
  • 19