Aug 18, 2005

protected in Java...

Here is an interesting question for Java developers. Consider the following classes, where class A is an abstract class that defines a protected method getInfo(), class B is a class that derives from A, and class C uses class A. In Java, is class C allowed to access the method getInfo()?

Classes defined above.

The answer may surprise some, but the actual answer is that it depends, because I have omitted one important piece of information that is required to answer this question, and that is piece of information, as surprising as it may be, is what package do these classes belong to.

If you refer to section 6.6.1 of the Java Language Specification, you will note that the definition indicates that:

Otherwise, if the member or constructor is declared protected, then access is permitted only when one of the following is true:

Of important note here is that classes within the same package as class A from the above example can access the method getInfo().

To drive this point home a bit more, consider the following cases:

Classes discussed below.

Here, we illustrate a Package A, which contains our abstract class A with the protected method getInfo(), class B which derives from class A, and class C and D which use class A and B, respectively. With this in mind, if class C instantiates an A and acquires information from it, it is OK.

If class D does the same call via an object B, this is not valid:

Now, if we do the above two calls in a separate package, this will not work. For example, in Package B, we have a class E, and should you attempt either of the above, this will result in a compilation error because now the two classes are not in the same package, and therefore, it is not accessible.

In Package C, I show a new class F that is derived class from class A (from Package A); it does not, however, overload getInfo(). If class H instantiates an F via an A as follows, this will also result in an error since the compiler does not know that you are actually manipulating an F and thus treats this as an error.

But is that really the reason the compilation fails? Let's see. If we have another class G that accesses the F directly, you will still have a compilation error.

Interestingly enough, this is covered in the example in section 6.6.7, in which it states that this cannot be permitted since class G is not involved in the implementation of A.getInfo().

So that brings us to Package D, which defines a class I that derives from class A and overrides the getInfo() method. Now in this package, if we try what we tried in the previous example in class J, we will note that it will now work. This is because class J is involved in the implementation of getInfo.

This is extremely interesting, especially if you come from a C++ background where packages do not exist. It is definitely an eye opener and will change my approach to class design!

Filed In