11

I am having a little trouble understanding the protected access modifier in java (or the design behind it). I thought it meant package access and access through objects that inherit the class containing an abstract member.

I wrote the following sample code. I see that the commented out line produces a compilation error if uncommented. Why can I access pro through a Second object in Second but not through a First object in Second?

package first;

public class First {

    protected void pro(){
        System.out.println("Can see protected method");
    }

}

package first;

public class InFirst {


    public static void main(String[] args){
        First fst = new First();
        fst.pro();
    }

}

package second;

import first.First;

public class Second extends First {

    public static void main(String[] args){

        First fst = new First();

//      fst.pro();

        Second sec = new Second();
        sec.pro();

    }
}
syb0rg
  • 8,057
  • 9
  • 41
  • 81
B M
  • 661
  • 2
  • 6
  • 13
  • 2
    You might to take a read through [Controlling Access to Members of a Class](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) for some more details – MadProgrammer Apr 11 '13 at 00:53
  • Good observation. This is normally confusing for a lot of developers. See the diagram below, maybe it is helpful. – Ryan Apr 11 '13 at 00:57
  • @MadProgrammer: Thanks, I have read this. I am basically confused by the phrase "by a subclass of its class in another package" that they use for the protected modifier. As shown above, I can access pro in Second but only through a Second object sec and not through a First object fst. – B M Apr 11 '13 at 00:59
  • @BM - I think the important detail you are missing in the subclass access of a parent class protected member, is that the access has to occur in the context of the subclass 'implementation' (the spec refers to body, same difference). The main method of any class is *not* considered part of its implementation which is why you get an error. – Perception Apr 11 '13 at 02:01
  • @Perception. If I write the same set of statements in a non-static method in Second, I still get the same error if I uncomment the commented line. So that is not the source of the error. – B M Apr 11 '13 at 16:09
  • @BM - you sure about that? Check out [this project](https://github.com/sevenhillsoftware/stackoverflow.git), and let me know if your sample is any different. – Perception Apr 11 '13 at 16:30
  • @Perception: Sorry, I am unable to see any source files from that link. Basically, in a non-static method from Second, I can't access pro on a First object just like in main method. Of course I can override pro in Second and also call pro from a non-static method, which is effectively calling pro on "this". I have checked all of this by writing sameple code. – B M Apr 11 '13 at 17:09
  • @BM - you have to drill down in the directories. [Here](https://github.com/sevenhillsoftware/stackoverflow/tree/master/src/main/java/misc/stack/first) for examples, are the classes in the `first` package. – Perception Apr 11 '13 at 17:16
  • Here's a simple [cheat sheet](http://stackoverflow.com/a/33627846/276052) that explains `protected` and the other access modifiers. – aioobe Nov 10 '15 at 16:00

4 Answers4

17

The webpage @MadProgrammer linked gives a decent explanation:

"The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package."

This means the protected member must be accessed directly through either the class it is defined in or a subclass of said class while also being within the appropriate package. It does not necessarily mean you can access the protected member through an instance of said class created within a subclass of said class. The focus is on the packages involved.

Here are your examples:

package first; // Current package

First fst = new First(); // from package first and does not extend anything
fst.pro();

Attempting to access member in question from which package? first

Is the (sub)class, which contains said member, or its parent class, which it inherits the member from, defined within that same package? Yes, First is defined in package first, so the protected member is accessible from First in package first.

package second; // Current package

First fst = new First(); // from package first and does not extend anything
fst.pro();

Attempting to access member in question from which package? second

Is the (sub)class, which contains said member, or its parent class, which it inherits the member from, defined within that same package? No, First is defined in package first, so protected makes the member inaccessible from First in package second.

package second; // Current package

Second sec = new Second(); // from package second and extends First from package first
sec.pro();

Attempting to access member in question from which package? second

Is the (sub)class, which contains said member, or its parent class, which it inherits the member from, defined within that same package? Yes, Second, which is defined in package second, inherits the member from First, so the protected member is accessible from Second in package second.

More examples for clarity:

package first; // Current package

Second sec = new Second(); // from package second and extends First from package first
sec.pro();

Attempting to access member in question from which package? first

Is the (sub)class, which contains said member, or its parent class, which it inherits the member from, defined within that same package? Yes, Second inherits the member from First, which is defined in package first, so the protected member is accessible from Second in package first.

package first; // Current package

Third third = new Third(); // from package third and extends Second from package second,
                           // which extends First from package first
third.pro();

Attempting to access member in question from which package? first

Is the (sub)class, which contains said member, or its parent class, which it inherits the member from, defined within that same package? Yes, Third inherits the member from Second, which inherits it from First where the member is defined (package first), so the protected member is accessible from Third in package first.

Ryan
  • 672
  • 8
  • 15
  • Thank you for the clear explanation. I also found this expanded diagram which covers all the cases, some of which are not covered in the link above. http://bmanolov.free.fr/javaprotection.php – B M Apr 11 '13 at 16:51
2

protected vs. defaultHere is a diagram to show the access level. You code belongs to the R(Reference) case in Convertible in the diagram. That is, reference in subclass in another package is not allowed to access.

Ryan
  • 2,825
  • 9
  • 36
  • 58
  • Thanks for the diagram. I am unable to read the text on it though. Is there a clearer link for it? – B M Apr 11 '13 at 01:02
  • Here is the link: http://www.programcreek.com/2009/02/diagram-to-illustrate-protected-and-default-difference/. – Ryan Apr 11 '13 at 01:03
1

Protected member in java

Same package-(it behaves like default)

It is accessible with in the sameclass,its child classes and also non child classes.(it behaves like default) You can even access protected members using parent or child reference.

Outside package-

It is accessible only to itz child class and the most important point here is that reference used must be of the same child class only

Anand
  • 51
  • 4
0

protected means visibile to other classes within the same package. since Second is in a different package 'second.Second', it cannot access .pro() in first.

if you created Second under the package name of 'first' - it would then work.

timzilla
  • 84
  • 6
  • 1
    That's not all protected means. It also means access from subclasses. That's why I can access pro from a Second object in Second. – B M Apr 11 '13 at 00:55
  • see what syborg said above. "sub-classes AND same package" – timzilla Apr 11 '13 at 00:57