32

パッケージには抽象クラスがありrelation、パッケージdatabase.relationにはそのサブクラスがありJoinますdatabase.operationsrelation。という名前の保護されたメンバーがあり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は表示されません

両方のクラスを同じパッケージに入れると、これは完全に機能します。誰かがこの問題を説明できますか?

4

4 に答える 4

27

それは機能しますが、他のインスタンスの変数ではなく、自分の変数にアクセスしようとするのはあなただけです(同じ継承ツリーに属している場合でも)。

理解を深めるには、次のサンプルコードを参照してください。

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

アクセス可能ですが、それ自体の変数にのみアクセスできます。

于 2010-06-18T17:36:32.357 に答える
13

保護に関するほとんど知られていない警告:

6.6.2保護されたアクセスの詳細

オブジェクトの保護されたメンバーまたはコンストラクターは、そのオブジェクトの実装を担当するコードによってのみ宣言されているパッケージの外部からアクセスできます。

于 2010-06-18T17:31:03.157 に答える
2

の場合protected、のインスタンスは、パッケージ外の他のインスタンス(、 )にJoinアクセスできません。mStructurerelRightrelLeft

編集:

この表は、この状況をかなりよく説明しています私はあなたの質問の犯人を[]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
于 2010-06-18T17:17:52.993 に答える
0

問題は、他のインスタンスで保護されたメンバーにアクセスしていることです。

複数のソリューションを適用できます。たとえば、可能であれば、親クラスで次の2つのメソッドを宣言できます。

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

と:

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

それはうまくいくはずです。現在、Relationには、子の内部での操作を可能にするメソッドを提供する責任があります。おそらく、このポリシーの背後にある理由は、非互換性を制限するために、同じソフトウェアバンドルの一部でない限り、子供が親の内部を混乱させてはならないためです。

于 2017-07-31T08:11:32.260 に答える