7

別の動作から始めましょう。メソッド/変数をプライベートとして宣言した場合でも、同じクラスの別のインスタンスがそれにアクセスできます。それは私がそれと一緒に暮らすことができるのは大丈夫です。私はこれらをインスタンスプライベートではなくクラスプライベートと呼んでいます。

ここで質問の部分です。たとえば、実行時に、thisクラス内のすべてのString変数がnullでないことを確認できるようにしたいので、nullの場合は、文字列「NULL」に変更する必要があります。

リフレクションを使用して変数を実行し、それらの値を取得できます。しかし、クラスを拡張してプライベート変数または保護された変数を追加すると、基本クラスはそれらにアクセスできなくなります。変数をsetAccessible使用する前に、変数を使用する必要があります。

それで、基本クラス(スーパークラス)がそのサブクラスからプライベート/保護された変数にアクセスできない理由を私に説明してください。それはそのサブクラスなので、私はそれを取得しません。この背後にある考え方は何ですか?

スーパークラスはそのサブクラスについて知らないはずですが、私の例ではそれは理にかなっていますね。

このようにサブクラスを制限できない、または制限すべきではないからですか?


更新: 回答に基づいて、私も知りたいです:同じクラスから別のインスタンスのプライベート変数にアクセスしないのはなぜカプセル化の違反と見なされないのですか?

4

4 に答える 4

7

それはカプセル化の違反であるのと同じくらい簡単です。あなたがそのクラスを一般化したとしても、別のクラスがあなたのクラスに到達して物事をいじり回すことができないはずです。たとえば、車両はどのようにして車について何かを知るのですか?基本クラスの要点はサブクラスを提供することですが、過保護な親のように、あなたが提案していることは多すぎるでしょう。

于 2009-05-22T18:59:11.040 に答える
7

更新の質問に答える(元の質問はすでに十分に回答されているため)privateの目的は、実装の詳細を非表示にして、それらの実装の詳細が依存関係にならないようにすることです。これがオブジェクト指向プログラミングの本質です。カプセル化により、さまざまな部分をそれぞれの領域に分離しておくことで、複雑さを管理しやすくします。

クラスはそれ自体の実装について知っているので、それを定義します。クラスの実装は、これらすべての詳細にすでに公開されているすべてのプライベートインスタンスを宣言するため、他のインスタンスへのアクセスを制限しても何も得られません。

この場合に非表示にすると、実際には複雑さが増します。これは、実際にはそれ以上の複雑さをカプセル化せずに、インスタンスレベルの可視性ではなく、クラスレベルの可視性を許可するためにアクセスレベルを追加する必要があるためです。

于 2009-05-22T22:30:45.417 に答える
4

継承とカプセル化がすべてです。

Javaの可視性ルールは次のように述べています

  1. プライベートメンバーは、それらを定義するクラスでのみアクセスできます
  2. 保護されたメンバーは、
    • それらを定義するクラス
    • それらを定義するクラスのサブクラス
    • それらを定義するクラスと同じパッケージ内の他のクラス

もちろん、あなたが言及するように、リフレクションであなたはルールを変更することができます(SecurityManagerがそれを禁止しない限り)

于 2009-05-22T19:02:24.060 に答える
0

私はそれを実用的で現実的な観点からもっと見る傾向があります:

public class Test1 {
    private int a = 1;

    public static void main(String s[]) {
        System.out.println((new Test1()).a);
        System.out.println((new Test1()).getA());
        System.out.println((new Test2()).getA());
    }

    public int getA() { return a; }
}

class Test2 extends Test {
    private int a = 2;

    public int getA() { return a; }
}

Test1のプライベートメンバーaにアクセスするためにどの構文を使用することを提案しますかTest2。とTest1書かれていると、Test2存在すらしないかもしれません。

同様に、基本クラス(スーパークラス)は、それがいつ継承されたかを知りません。基本クラスがいつ継承されたかを認識できるようにするには、基本クラスから継承するときに基本クラスを変更できる必要があります。あなたはArrayList私が書くときに私のローカルコピーをどうにかして修正するべきだと提案していますか?

class MyArrayList extends ArrayList

そして、私があなたのコンピューターで私のコードを実行することを決めた日はどうなりますか、あなたはArrayListそれについて知っている私の修正されたコピーを手に入れますMyArrayListか、それとも私はあなたのコンピューターでコピーを修正しますか?

これらの問題はどういうわけか克服できますか?そうです。それを許可することに何か価値はありますか?私が見ることができるものはありません。

于 2009-05-22T19:26:13.857 に答える