0

According to my understanding, a protected method can be accessed by any class within the same package, but only subclasses to this class can access from other packages .

package Parent;

public class Parent {
    protected void display() {
    //Code here
    }

}
import Parent;

package Child;

class Child extends Parent{
    void view(Parent p1) {
        this.display(); // Success
        p1.display();  // Error
    }

    void next(Parent p2) { 
        p2.foo(); //Success
    }
}   

Here this.display() is successful because the child class is responsible for implementation. But p1.display() does not work as p1 is not part of Child class. How can we justify this behaviour in the case of accessing protected methods from classes within the same package?

WilQu
  • 7,131
  • 6
  • 30
  • 38
seriousgeek
  • 992
  • 3
  • 13
  • 29
  • 2
    Protected methods can be accessed by a subclass of a class. – christopher Jun 05 '13 at 09:47
  • 4
    It's not clear what you mean. Are you surprised by the behaviour, or do you understand that that's what the spec says, and you're trying to determine the reason behind it? – Jon Skeet Jun 05 '13 at 09:49

3 Answers3

2

Your

p1.display();

has the potential of running a method implemented in any package, depending on which exactly Parent subclass you received. This would be in clear violation of the intent behind protected, which is specifically to allow classes designed for extension to provide encapsulated methods to their children.

If that call was allowed, it would be trivially easy for a rogue class to access encapsulated methods from a class completely foreign to it.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
1

If you use super.display() it will work. The reason is that protected methods in parent are always visible to child classes whether they are in same package or not. When you just say p1.display() it expects the method to be public as both classes are in different package.

Please read the following to get more understanding on this.

In Java, difference between default, public, protected, and private

Community
  • 1
  • 1
Harish Kumar
  • 528
  • 2
  • 15
1

The example you have provided is calling the method using an instance of Parent passed to the child. The spec states that access to the field or instance method must be from the subclass when the scope is protected. Notice the portion of the spec that states, access is permitted if and only if the type of the expression Q is S or a subclass of S. In your example the ExpressionName is p1, which is an instance of Parent, making its type not Child or a subclass of Child therefore access is disallowed.

Let C be the class in which a protected member is declared. Access is permitted only within the body of a subclass S of C.

In addition, if Id denotes an instance field or instance method, then:

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.

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

I think I see the point your attempting to make, since Child is a subclass of Parent, when we pass an instance of Parent into a method on Child we should be able to call its protected methods. The rules of the specification prohibit this.

Specification

Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189