1

2つのクラス(1つの親と1つの子)があります。どちらもプライベート変数を使用して値を格納しますが、親はセッターを提供しないでください(xとyはコンストラクターで指定され、ある種の不変です)。Bは、xとyのセッターでAを拡張する必要があります。そうするための一般的な方法はありますか?

class A{
    private int x;
    private int y;

    A(int x, int y){
        this.x = x;
        this.y = y;
    }

}

class B extends A{

    public void setx(int x){
        this.x = x;
    }

    //same for y
}

いくつかの考え

  • 変数はプライベートである必要があります
  • 親のxとyは不変である必要があります
  • Bはパブリックセッターを提供する必要があります
4

5 に答える 5

3

基本クラスのように変数を宣言protectedし、子クラスにgetterとsetterを記述します。

于 2012-11-13T10:43:56.477 に答える
3

変数を不変にしたい場合は、

class B extends A{

    public B(int x, int y){
          super(x, y);
    }
}

現時点では、Aのx変数とy変数は不変ではありません。それらを不変にするために、それらの前にfinal

これは、xとyがプライベートであるため、それらを割り当てることができる唯一の方法です。セッターが必要な場合は、変数を保護する必要があります。

個人的に私は不変性の大ファンなので、セッターではなくこれを行います-オブジェクトの作成は通常非常に安価です。

于 2012-11-13T10:44:38.753 に答える
1

プライベートメンバー変数を設定したり、メソッド(ここではメソッドではコンストラクターも意味します)を設定したりすることはできません(技術的には可能ですが、意味がありません)。変数を派生クラスから設定可能にする場合は、変数を保護する必要があります。

編集:ただし、基本クラスで保護された「ヘルパー」セッターを定義し、派生クラスのパブリックセッターからこの保護されたヘルパーセッターを呼び出すことができます。

2番目の編集:別の可能性は、基本クラスで抽象ゲッターを定義し、派生クラス(テンプレートパターン)でゲッター、セッター、およびプライベートフィールドを実装することです。

于 2012-11-13T10:42:45.573 に答える
0

これは奇妙な質問であり、不変であるが変更可能であり、プライベートであるがパブリックです...誰もが言っているように、正しい方法はそれらを保護することです。

とにかく、Javaでは、セキュリティマネージャが文句を言わない場合は、汚いトリックを使用できます。これを確認してください。

import java.lang.reflect.Field;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Priv
{
    public static class A
    {
        private final int x;
        public A(int x)
        {
            this.x = x;
        }
    }

    public static class B extends A
    {
        public B(int x)
        {
            super(x);
        }

        public void setX(int x)
        {
            Class c = A.class;
            try
            {
                 Field f = c.getDeclaredField("x");
                f.setAccessible(true);
                f.set(this, x);
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NoSuchFieldException ex) {
                Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
            } catch (SecurityException ex) {
                Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        public int getX()
        {
            int v = 0;

            try {
                Class c = A.class;
                Field f = c.getDeclaredField("x");
                f.setAccessible(true);
                v = f.getInt(this);
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NoSuchFieldException ex) {
                Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
            } catch (SecurityException ex) {
                Logger.getLogger(Priv.class.getName()).log(Level.SEVERE, null, ex);
            }

            return v;
        }
    }

    public static void main(String[] args)
    {
         B b = new B(5);

         System.out.println("b.x is " + b.getX());

         b.setX(42);

        System.out.println("b.x now is " + b.getX());
    }

}
于 2012-11-13T11:07:18.547 に答える
0

不変の概念はありません。プライベートであるスーパークラスの変数を再初期化するためにsuperを呼び出す子クラスのセッターメソッドまたはコンストラクターがあります。

不変は本質的にスレッドセーフです。

于 2012-11-13T13:29:22.880 に答える