1

これがばかげた質問ではないことを願っています。
3 つの基本コンストラクターを持つ

public MyClass(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // TODO Auto-generated constructor stub
}

public MyClass(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
}

public MyClass(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
}

superそれぞれが最初にクラス コンストラクターを呼び出します。では、このようなプライベート メソッドに入れなければならないすべての一般的なコンストラクタ コードを意味するのでしょうか?:

public MyClass(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    common(context);
}

public MyClass(Context context, AttributeSet attrs) {
    super(context, attrs);
    common(context);
}

public MyClass(Context context) {
    super(context);
    common(context);
}

private void common(Context context) { ... }

共通コードのコンストラクターをチェーンできると思いましたが、コンストラクター呼び出しはコードの最初のステートメントでなければならないというエラーが表示されます。

public MyClass(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this(context, attrs);
}

public MyClass(Context context, AttributeSet attrs) {
    super(context, attrs);
    // Some code
    this(context);
}

public MyClass(Context context) {
    super(context);
    // Some more code
}

また、最初のステートメントは、スーパー コンストラクター呼び出しまたはクラス コンストラクター呼び出しのいずれかであり、両方にすることはできません。

Constructor call must be the first statement in a constructor
4

4 に答える 4

6

最良の方法は this() を使用することです - 新しいメソッドを作成する必要はなく、DRY 原則を尊重します (自分自身を繰り返さないでください)

    public MyClass(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
      // your code here
    }

    public MyClass(Context context, AttributeSet attrs) {
       // Assuming 0 is the default value of defStyle, else pass the default value
       this(context, attrs, 0);
    }

    public MyClass(Context context) {
        // Assuming null is the default value for attrs
        this(context, null);
    }
于 2013-04-28T14:47:57.547 に答える
3

別のメソッドを作成する必要はありません。DRY 原則を尊重すれば簡単です。

 public MyClass(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
      // your code here
    }
    public MyClass(Context context, AttributeSet attrs) {
       this(context, attrs,null);
    }
    public MyClass(Context context) { 
        this(context,null,null);
    }

このように使用できます

于 2013-04-28T14:48:52.213 に答える
0

さて、共通コードをコンストラクターに入れ、最後のパラメーター int defStyle に注意して他のすべてのコンストラクターから呼び出すようにしてください。0 が defStyle のデフォルトであると想定しています。

public MyClass(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    common(context);
}

public MyClass(Context context, AttributeSet attrs) {
    this(context, attrs,0);
}

public MyClass(Context context) {
    this(context,null,0);
}

private void common(Context context) { ... }
于 2013-04-28T15:04:43.283 に答える
0

私が提案するのは、最もパラメーター化可能なコンストラクターに共通コードを配置し、他のすべての (パラメーター化可能性の低い) コンストラクターからそのコンストラクターを呼び出すことです。もちろん、現在欠落している引数のいくつかのデフォルト値を使用します (同じクラスのコンストラクターをthis(...)ステートメントでチェーンできます)。super(...)拡張しているスーパークラスが適切に設計されている場合は、最もパラメーター化可能なコンストラクターを使用して、チェーン (ステートメントを使用) によって最もパラメーター化可能なコンストラクターを呼び出すことができるはずです。

それがあなたのケースでうまくいかない場合、プライベートメソッドはこれに対処するための非常に優れた方法です。通常、それをさらに回避しようとしてもメリットはありません。

于 2013-04-28T14:53:47.293 に答える