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

发布于 2024-09-06 08:32:44 字数 955 浏览 13 评论 0原文

我在 database.relation 包中有一个抽象类 relation,在 database.operations< 包中有一个它的子类 Join /代码>。 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);
        }
    }
}

Onlines

this.copyStructure(mRelLeft.mStructure);

中,

for (final Header header : mRelRight.mStructure) {

我收到以下错误:

字段 Relation.mStructure 不可见

如果我将两个类放在同一个包中,则效果非常好。谁能解释一下这个问题吗?

I have an abstract class, relation in package database.relation and a subclass of it, Join, in package database.operations. relation has a protected member named mStructure.

In 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

If I put both classes in the same package, this works perfectly. Can anyone explain this issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

划一舟意中人 2024-09-13 08:32:44

它有效,但只有您的孩子尝试访问它自己的变量,而不是其他实例的变量(即使它属于同一继承树)。

请参阅此示例代码以更好地理解它:

//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);

它是可访问的,但只能访问其自己的变量。

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:

Children.java:8: parentVariable has protected access in parentpackage.Parent
    System.out.print(withParent.parentVariable);

It is accessible, but only to its own variable.

樱&纷飞 2024-09-13 08:32:44

关于受保护的鲜为人知的警告:

6.6.2 有关受保护访问的详细信息

受保护的成员或构造函数
对象可以从外部访问
声明它的包
仅由负责的代码
该对象的实现。

A little known caveat about protected:

6.6.2 Details on protected Access

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.

空‖城人不在 2024-09-13 08:32:44

如果受保护,您的Join实例无法访问其他实例中的mStructurerelRightrelLeft< /code>) 位于包外。

编辑:

表格此处很好地解释了这种情况。我用 [] 标记了您问题中的罪魁祸首

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

If protected, your instance of Join cannot access the mStructure in other instances (relRight, relLeft) outside the package.

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
以酷 2024-09-13 08:32:44

问题是您正在访问其他实例受保护的成员。

您可以应用多种解决方案,例如,如果可能的话,您可以在父类中声明这两个方法:

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);
    }
  }
}

然后在子代码中替换:

this.copyStructure(mRelLeft.mStructure);

for (final Header header :mRelRight.mStructure) {
  if (!mStructure.contains(header)) {
    mStructure.add(header);
  }
}

With:

this.copyRelationStructure(mRelLeft);
this.mergeRelationStructure(mRelRight);

这应该可行。现在 Relation 有责任提供允许对其子级进行自身内部操作的方法。这项政策背后的原因可能是孩子们不应该弄乱父母的内部结构,除非它们是同一软件包的一部分,以限制不兼容性。

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:

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. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文