Question

I have just got weird error which involves protected modifier.

I have following code:

package p1;

public class C1 {
    protected void doIt() {}
}


package p2;

public class C2 extends p1.C1 {
    private C1 c1_instance;
    public void doItAgain() {
        c1_instance.doIt(); // wtf!!!!
    }
}

I get error, stating that doIt() has protected access and can't be accessed! But I am in the sub class and do have and access to doIt() method.

Is not it a bug?

Was it helpful?

Solution

I also had the impression what protected meant "accessible from the same package or from a subclass" but the Java Language Specification is of course more precise, and explains that in a subclass S of C, "If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S."

So you can only access a protected method of the superclass via a reference to the subclass you are calling from, like this:

public class C2 extends C1 {
    private C2 c2_other_instance;
    public void doItAgain() {
        c2_other_instance.doIt();
    }
}

If you explain why you want to access one instance of the superclass from a different instance of the subclass then someone might be able to suggest a better design. Otherwise you will have to make the method public or put the classes in the same package.

OTHER TIPS

In Java, you can't call protected methods on a different instance of the base class, even from within a subclass:

public class C2 extends p1.C1 {
    private C1 c1_instance;
    public void doItAgain() {
        doIt();             // fine
        c1_instance.doIt(); // disallowed
    }
}

The only exception is when both the base class and the subclass are in the same package.

To quote the Java OO tutorial:

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.

Protected is equivalent to package level access; you can't access the method if you are in a different package.

You should be able to call doIt() directly without going through the c1_instance object however, as C2 is a subclass.

From http://download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

"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."

C2 may be a sub class of C1, but this does not mean it can access those methods on a different instance, i.e. c1_instance may not be an instance of C2. You could access it if it was in the same package.

No, protected assures access in the same package and in the descendant classes. You are neither in the same package nor you are accessing it directly from a descendant class. C2 is a descendant but c1_instance isn't.

If your method is declared as protected then you can access this within this class , withing the package and within the subclass.

now here is the question , why is there an error inspite of accessing this protected member from its subclass. the answer is to access the protected method from a subclass your subclass should use the method directly from the direct subclass. here the direct subclass is C2 but the instance c1_instance is not. you can use this method directly (doIt() in place of c1_instance.doIt())

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top