简体   繁体   English

当子类位于不同的包中时,为什么我的子类不能访问其超类的受保护变量?

[英]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实例在包之外的其他实例( relRightrelLeft )中无法访问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.

相关问题 为什么不同包中的子类无法通过超类实例访问其在另一个包中的超类的受保护字段? - Why a subclass in a different package is unable to access the protected fields of its superclass in another package through superclass instance? 受保护的为什么不能在不同的包子类中访问? - protected can't access in different package subclass why? 如何在子类中访问超类的“protected static”变量,其中子类位于不同的包中..? - How can ‘protected static’ variable of superclass be accessed in the subclass, where subclass resides in different package..? 当子类在超类中受到保护时,子类如何使变量成为私有的? - How can a subclass make a variable private when it is protected in superclass? 类无法使用来自不同包的反射来访问其自己的受保护的成员变量 - Class can't access its own protected member variable using reflection from different package 无法从不同jar中的同一个包访问超类的受保护成员 - Can't access protected member of superclass from same package in different jar 访问超类中子类的受保护字段? - Access protected fields of a subclass in a superclass? 子类访问中的受保护方法,它位于不同的包中 - Protected methods in subclass access which is in different package 为什么我的子类不继承其超类的私有实例变量? - Why doesn't my subclass inherit the private instance variables of its superclass? Java:对超类对象上的子类的受保护访问限制 - Java : Protected access restriction for subclass on superclass object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM