6

派生クラスに基本クラスのインスタンスを作成し、保護されたメンバーにアクセスしようとしました。

基本クラスをインスタンス化せずに、派生クラスの保護されたメンバーに直接アクセスできます。

基本クラス:

package com.core;

public class MyCollection {

      protected Integer intg;
}

同じパッケージの派生クラス-

package com.core;

public class MyCollection3 extends MyCollection { 

 public void test(){

  MyCollection mc = new MyCollection();
  mc.intg=1; // Works
 }
}

別のパッケージの派生クラス-

package secondary;

import com.core.MyCollection;

public class MyCollection2 extends MyCollection{ 

 public void test(){
  MyCollection mc = new MyCollection();
  mc.intg = 1; //!!! compile time error - change visibility of "intg" to protected
 }
}

派生クラスも同じパッケージにあるが、派生クラスが別のパッケージにある場合は、基本クラスのインスタンスを使用して、派生クラスの保護されたメンバーにアクセスするにはどうすればよいですか?

保護されたメンバーを「静的」としてマークすると、別のパッケージにある派生クラスの基本クラスのインスタンスを使用して、基本クラスの保護されたメンバーにアクセスできます。

4

6 に答える 6

10

あなたはこれを行うことができないというのは正しいです。フィールドにアクセスできない理由は、クラスと同じパッケージに含まれておらず、同じクラスの継承されたメンバーにアクセスしていないためです

最後のポイントは重要なポイントです-あなたが書いたなら

MyCollection2 mc = new MyCollection2();
mc.intg = 1;

自分のクラスの保護されたメンバー(継承を通じてそのクラスに存在する)を変更しているので、これは機能します。ただし、あなたの場合、別のパッケージの別のクラスの保護されたメンバーを変更しようとしています。したがって、アクセスが拒否されるのは当然のことです。

于 2010-06-30T11:23:44.700 に答える
3

Javaチュートリアルによると:

保護された修飾子は、メンバーが(package-privateの場合と同様に)独自のパッケージ内でのみアクセスでき、さらに、別のパッケージ内のそのクラスのサブクラスからのみアクセスできることを指定します。

そしてあなたの場合、あなたは別のオブジェクトの変数にアクセスしています。偶然にも、現在のクラスと同じクラスがありますが、可視性チェックではそれをチェックしません。

したがって、2回目は別のパッケージに含まれているためにアクセスが拒否され、1回目は同じパッケージに含まれているためにアクセスが許可されます(サブクラスであるためではありません)。

于 2010-06-30T11:28:39.983 に答える
3

クラスメンバーがいる場合、protected2つのケースがあります。

  1. サブクラスが同じパッケージにある場合
  2. サブクラスが別のパッケージにある場合

I.同じパッケージ:
-継承を介してアクセスできます
-親クラス
IIのインスタンスを作成することでアクセスできます。別のパッケージ:
-継承を介してのみアクセスできます

すべての使用例については、以下の表を参照してください。

ここに画像の説明を入力してください

出典:SCJP本。

于 2015-03-24T06:08:31.437 に答える
1

要するに、それは実際には不可能です。デザインを考え直すべきだと思います。

ただし、それがあなたのやりたいことであると確信している場合は、回避策があります。インスタンスを取得し、ユーザーに代わっての値を設定する保護されたメソッドを追加できます。MyCollectionintg

package com.core;

public class MyCollection {

    protected Integer intg;

    protected void setIntg(MyCollection collection, Integer newIntg) {
        collection.intg = newIntg;
    }
}

これで、サブクラスはこのメソッドにアクセスできます。

package secondary;

import com.core.MyCollection;

public class MyCollection2 extends MyCollection{ 

    public void test(){
        MyCollection mc = new MyCollection();
        setIntg(mc, 1);
    }
}

ただし、これは非常に奇妙な方法であることに注意してください。このルートを進む前に、デザインを再考する必要があることをもう一度お勧めします。

于 2010-06-30T11:30:21.550 に答える
0

Javaのメンバーアクセシビリティルールによれば、クラスの保護されたメンバーに拡張せずにアクセスすることはできません。

次のことを試すことができます。

package secondary;

import com.core.MyCollection;

public class MyCollection2 extends MyCollection{ 

 public void test(){
  intg = 1; 
 }
}

新しいインスタンスを作成する代わりに、値を割り当ててみてください。それが動作します。

于 2010-06-30T11:26:25.140 に答える
0

MyCollectionクラスの新しいオブジェクトを使用してアクセスした場合、派生クラス(別のパッケージに含まれている)の保護された変数にアクセスすることはできません。intg=1と書くだけです。このように(新しいMyCollection)を作成せずに直接:

package secondary;
import com.core.MyCollection;       
public class MyCollection2 extends MyCollection{ 

 public void test(){

     intg = 1;

 }
}
于 2014-06-06T12:05:48.130 に答える