(EDIT: theycallmemorty's answer gives the practical advice to avoiding this problem in your case. This answer gives the reasons for why you have to follow that advice, i.e. why the language has been designed that way.)
You can only access a protected member of another object which is of the same type as the accessing code (or a subclass) - even though the member is declared in a supertype.
From the Java Language Specification, section 6.6.2:
Let C be the class in which a
protected member m 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.
This is to allow a type to access members relevant to its own inheritance tree, without defeating encapsulation of other classes. For example, suppose we have:
A
/
B Other
/
C
and A declared a protected member x
. Without the rule working the way it does, you could get round encapsulation by putting a member in Other
:
public int getX(A a)
{
return a.x;
}
and just calling that passing in an instance of B
or C
- the member would effectively become public, because you could always work around it by introducing another class... not a good idea. With the current rule, you'd have to subclass B
or C
- which you may not be able to in the first place.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…