1. ホーム
  2. java

[解決済み] コンストラクタでsuper()の前に計算を行うことは可能ですか?

2023-05-22 07:28:52

質問

TextBoxオブジェクトを引数とする単一引数コンストラクタを持つクラスBaseがあるとします。私は次のフォームのクラスSimpleを持っている場合。

public class Simple extends Base {
  public Simple(){
    TextBox t = new TextBox();
    super(t);
    //wouldn't it be nice if I could do things with t down here?
  }
}

superの呼び出しはコンストラクタの最初の呼び出しでなければならないというエラーが表示されます。しかし、奇妙なことに、私はこれを行うことができます。

public class Simple extends Base {
  public Simple(){
    super(new TextBox());
  }
}

なぜ、これは許可されているのに、最初の例は許可されていないのでしょうか?サブクラスを最初にセットアップする必要があることは理解できますし、スーパーコンストラクタが呼び出される前にオブジェクト変数をインスタンス化することを許可しないかもしれません。しかし、tは明らかにメソッド(ローカル)変数であり、なぜそれを許可しないのでしょうか?

この制限を回避する方法はありますか?super を呼び出す前に構築し、コンストラクタを入力した後に構築する可能性があるものに変数を保持する良い安全な方法はありますか? あるいは、より一般的には、スーパーが実際に呼び出される前に、しかしコンストラクタ内で計算を行うことを可能にするのでしょうか?

ありがとうございます。

どのように解決するのですか?

はい、この単純なケースに対する回避策があります。プライベートなコンストラクタを作成し、そのコンストラクタに TextBox を引数として取るプライベート コンストラクタを作成し、パブリック コンストラクタからそれを呼び出すことができます。

public class Simple extends Base {
    private Simple(TextBox t) {
        super(t);
        // continue doing stuff with t here
    }

    public Simple() {
        this(new TextBox());
    }
}

より複雑なものについては、ファクトリーや静的ファクトリーメソッドを使用する必要があります。