我在包relation
中有一个抽象类database.relation
,在包Join
中有一个子类database.operations
。 relation
有一个名为mStructure
的受保护成员。
在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);
}
}
}
在线
this.copyStructure(mRelLeft.mStructure);
和
for (final Header header : mRelRight.mStructure) {
我收到以下错误:
字段Relation.mStructure不可见
如果我将两个类放在同一个包中,这可以很好地工作。任何人都可以解释这个问题吗?
答案 0 :(得分:25)
它有效,但只有孩子们试图访问拥有变量,而不是其他实例的变量(即使它属于同一个继承树)。
请参阅此示例代码以更好地理解它:
//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
}
}
如果我们尝试使用我们得到的withParent.parentVariable
进行编译:
Children.java:8: parentVariable has protected access in parentpackage.Parent
System.out.print(withParent.parentVariable);
它是可访问的,但仅限于它自己的变量。
答案 1 :(得分:13)
关于protected的一个鲜为人知的警告:
6.6.2有关受保护访问的详细信息
受保护的成员或构造函数 可以从外部访问对象 声明它的包 只有负责的代码 该对象的实现。
答案 2 :(得分:2)
如果protected
,您Join
的实例无法访问软件包外的其他实例mStructure
,relRight
中的relLeft
。
编辑:
表here相当好地解释了这种情况。我用[]
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
答案 3 :(得分:0)
问题是您正在访问其他受实例保护的成员。
您可以应用多个解决方案,例如,如果可能,您可以在父类中声明这两个方法:
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);
}
}
}
然后在childs代码替换:
this.copyStructure(mRelLeft.mStructure);
for (final Header header :mRelRight.mStructure) {
if (!mStructure.contains(header)) {
mStructure.add(header);
}
}
使用:
this.copyRelationStructure(mRelLeft);
this.mergeRelationStructure(mRelRight);
那应该有用。现在,Relation有责任提供允许其子项内部操作的方法。这个政策背后的原因可能是孩子们不应该弄乱父母的内部,除非他们是同一软件包的一部分,以限制不兼容性。