[英]Why can't my subclass access a protected variable of its superclass, when it's in a different package?
I have an abstract class, relation
in package database.relation
and a subclass of it, Join
, in package database.operations
. 我有一个抽象类, relation
在包database.relation
和它的一个子类, Join
,在包database.operations
。 relation
has a protected member named mStructure
. relation
具有名为mStructure
的受保护成员。
In Join
: 在Join
:
public Join(final Relation relLeft, final Relation relRight) {
super();
mRelLeft = relLeft;
mRelRight = relRight;
mStructure = new LinkedList<Header>();
this.copyStructure(mRelLeft.mStructure);
for (final Header header :mRelRight.mStructure) {
if (!mStructure.contains(header)) {
mStructure.add(header);
}
}
}
On lines 上线
this.copyStructure(mRelLeft.mStructure);
and 和
for (final Header header : mRelRight.mStructure) {
I get the following error: 我收到以下错误:
The field Relation.mStructure is not visible 字段Relation.mStructure不可见
If I put both classes in the same package, this works perfectly. 如果我将两个类放在同一个包中,则效果很好。 Can anyone explain this issue? 谁能解释这个问题?
It works, but only you the children tries to access it own variable, not variable of other instance ( even if it belongs to the same inheritance tree ). 它有效,但是只有您自己的孩子会尝试访问它自己的变量,而不是其他实例的变量(即使它属于同一继承树)。
See this sample code to understand it better: 请参阅以下示例代码以更好地理解它:
//in Parent.java
package parentpackage;
public class Parent {
protected String parentVariable = "whatever";// define protected variable
}
// in Children.java
package childenpackage;
import parentpackage.Parent;
class Children extends Parent {
Children(Parent withParent ){
System.out.println( this.parentVariable );// works well.
//System.out.print(withParent.parentVariable);// doesn't work
}
}
If we try to compile using the withParent.parentVariable
we've got: 如果我们尝试使用withParent.parentVariable
进行编译, withParent.parentVariable
得到:
Children.java:8: parentVariable has protected access in parentpackage.Parent
System.out.print(withParent.parentVariable);
It is accessible, but only to its own variable. 它是可访问的,但只能访问其自己的变量。
A little known caveat about protected : 关于保护的一些鲜为人知的警告:
6.6.2 Details on protected Access 6.6.2有关受保护访问的详细信息
A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object. 对象的受保护成员或构造函数只能从负责该对象实现的代码在其中声明该对象的包外部访问。
If protected
, your instance of Join
cannot access the mStructure
in other instances ( relRight
, relLeft
) outside the package. 如果protected
,则您的Join
实例在包之外的其他实例( relRight
, relLeft
)中无法访问mStructure
。
EDIT: 编辑:
The table here explains this situation fairly well. 此处的表格很好地说明了这种情况。 I marked the culprit in your question with []
s 我用[]
标记了您问题中的罪魁祸首
Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y [Y] Y N
no modifier Y Y N N
private Y N N N
The problem is that you are accessing other instance protected member. 问题是您正在访问其他实例保护的成员。
You can apply multiple solutions, for example if possible you can declare in the parent class these two methods: 您可以应用多种解决方案,例如,如果可能的话,您可以在父类中声明以下两种方法:
protected void copyRelationStructure(Relation r) {
this.copyStructure(r.mStructure);
}
protected void mergeRelationStructure(Relation r) {
for (final Header header: r.mStructure) {
if (!mStructure.contains(header)) {
mStructure.add(header);
}
}
}
And then in childs code replace: 然后在childs代码中替换:
this.copyStructure(mRelLeft.mStructure);
for (final Header header :mRelRight.mStructure) {
if (!mStructure.contains(header)) {
mStructure.add(header);
}
}
With: 带有:
this.copyRelationStructure(mRelLeft);
this.mergeRelationStructure(mRelRight);
That should work. 那应该工作。 Now Relation has the responsibility to provide methods that allow operations with itself inners to its children. 现在,Relationship有责任提供允许对其子对象进行内部操作的方法。 Probably the reason behind this policy is that children should not mess with parent's internals unless they are part of the same software bundle in order to limit incompatibilities. 这项政策背后的原因可能是,除非限制其兼容性,否则孩子们不应破坏父母的内部知识。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.