2016-04-07 2 views
5

私は、コンストラクタのチェーンが最小のコンストラクタから最大のものになることを理解します。例コンストラクタなしでチェーン化する()

public MyChaining(){ 
     System.out.println("In default constructor..."); 
    } 
    public MyChaining(int i){ 
     this(); 
     System.out.println("In single parameter constructor..."); 
    } 
    public MyChaining(int i,int j){ 
     this(j); 
     System.out.println("In double parameter constructor..."); 
    } 

また、私はthis()super()への呼び出しは、最初の行になければならないことを理解してください。しかし、限界とチェーンコンストラクターをバイパスすることは可能ですか(そうなら、それは効率的ですか)?

たとえば、私はいくつかのコードを共有するこの2つのコンストラクタを持っています。

public Location(String _Name) throws IOException, JSONException { 
     //Three lines of unique code (must be executed before the shared code) 
     //Shared code 
    } 

    public Location(JSONObject json) { 
     //Shared code 
    } 

第1のコンストラクタが第2のコンストラクタを呼び出すことはどのような方法で可能ですか?

+0

@フィリピンはい、それはそうであり、そうするでしょう。私は他の場所で回答が見つからなかったので連鎖することができるかどうか疑問に思っていた。 – Akaitenshi

答えて

4

あなたはstatic機能

JSONObject foo(String)

を持っているなら、あなたは、実際のコンストラクタロジックが多く広がっているので、私は、かなり読めない最大のパターンに最小のコンストラクタからチェーンを見つける

public Location(String _Name) throws IOException, JSONException { 
    this(foo(_Name)); 
} 
3

thisを呼び出さずに共有コードを実行する唯一の方法は、両方のコンストラクターが共有コードを含む初期化メソッドを呼び出すことです。

public Location(String _Name) throws IOException, JSONException { 
    //Three lines of unique code (must be executed before the shared code) 
    init(); 
} 

public Location(JSONObject json) { 
    init(); // perhaps the JSONObject should be passed to that method, otherwise 
      // that parameter is useless. On the other hand, I don't see a 
      // JSONObject in the other constructor 
} 

private void init() { 
    // shared code 
} 
+0

はい、私はそれがこのようにできることを知っています。私はそれが連鎖してのみ行うことができるかどうか疑問に思っていた。 – Akaitenshi

+1

init()メソッドには別の問題があります。そのメソッドの最後のインスタンスフィールドを初期化することはできません。 –

+0

@Akaitenshi Chainingは 'this();'でのみ行われ、コンストラクタの最初の行でなければなりません。 – Eran

1

何か別の回答:しないでください。

コンストラクターはクラスの他のメンバーと同様です。コンストラクターは「完全に」意味をなす必要があります。ユーザーに完全に「異なる」または「独立した」「インターフェース」を提供するコンストラクターは、コードの匂いのように見えます。

表示されます。クラスを通って線を描くことができれば、いくつかの要素が左側に残り、多くの要素がその行の右側に移動することがわかります。それはあなたのクラスをその "行"に沿って分割し、代わりに2つのクラスを作成する必要があるかもしれないということを示しています。

異なるコンテキストから同じ種類のオブジェクトを実際に作成したい場合は、次に「共通分母のピースX」を特定しようとする。そのXのためのコンストラクタを提供します。そして、その共通のコンストラクタを異なる方法で使用する可能性のあるファクトリメソッドを使用します。これは、あなたが

static Location generateLocationFromFoo(Foo foo) { ... } 
static Location generateLocationFromBar(Bar bar) { ... } 

あるいはさらに一歩行くような、同じクラス内の静的メソッドを提供し、あなたのため実際の場所のオブジェクトを生成するために使用される別のファクトリクラスを作成するいずれかのことを意味します。

+0

申し訳ありませんが、私はあなたの最後の文を完全に理解していません。つまり、同じクラス内のメソッドからコンストラクタを呼び出して、このメソッドを使用してObjectをインスタンス化できますか? – Akaitenshi

+0

答えを更新しました。助けてくれることを望む。 – GhostCat

+0

私は 'generateLocation'の内部でコンストラクタを呼び出し、私のメインでオブジェクトを欲しいときに' objName.generateLocation() 'を呼び出します。 – Akaitenshi

1

を書くことができます異なる方法。私はそれが最も読みやすい見つける

  • は完全にインスタンス初期
  • を扱う1「メイン」コンストラクタは、他のすべてのコンストラクタはまた、私はやや長い嫌い

それを呼び出す持っているがあります(シンプルなコンストラクタからドリルダウンすると実際のコードに到達するのは難しい)ので、重複したコードを意味しない限り、他のすべてのコンストラクタを直接「メイン」コールと呼びます。

このルールで実際に防止しようとしているもの(半初期化されたオブジェクトの使用など)を行わない限り、静的メソッドを呼び出すことで、常に「this()は最初のステートメントにする必要があります。 ハーフ・イニシャライズ・オブジェクトを使用できないようにするには、呼び出される関数がスタティックである必要があります。

関連する問題