2016-09-13 5 views
0

私は抽象クラスChildClassから継承していますが、実装するコンストラクタは4つあります。
すべてのコンストラクタに共通の一般的な設定があります。
これらのタスクを抽象化して、すべてのコンストラクタで呼び出すことができます。
オブジェクトがすべてのコンストラクタシグネチャで呼び出されるのではなく、初期化されるときに特定のメソッドを呼び出す方法はありますか?オブジェクトの初期化時にメソッドを呼び出す

+0

outオブジェクトがインスタンスメソッドを作成してコンストラクタを使用すると、 ''これを使用して中央コンストラクタに委任する – ravthiru

+2

どれ可能性(...)を呼び出すことはできません?、オブジェクトを作成することができますかそれ以外にも、メソッドがオーバーライドされた場合、問題が発生する可能性があります。オーバーライドされたメソッドがスーパーコンストラクタによって呼び出されたが、まだ初期化されていないサブクラスのフィールドを使用する場合 – Thomas

+0

トーマスが示唆していることは、これを行う最も一般的な方法です(可能な場合)。たとえば、オプションがオプションの場合、デフォルト値でコンストラクタに委譲します。 –

答えて

1

すでにコメントに記載されているように、共通の初期化コードを呼び出す方法の1つはthis(...)の使用で、つまり別のコンストラクタから1つのコンストラクタを呼び出します。ただし、この呼び出しはコンストラクタの最初の文でなければならないため、必要なものを提供しない可能性があります。

また、すべてのコンストラクタで適切な場所(コンストラクタの末尾など)に初期化メソッド(最も一般的な名前はinit())を呼び出すことができます。ただし、サブクラスがそのメソッドをオーバーライドすると、スーパーコンストラクターがメソッドを呼び出す未定義の状況が発生する可能性があり、サブクラスの未初期化フィールドを使用します。メソッドをオーバーライドできないように、つまり最終的に宣言するかプライベートにするかを緩和する必要があります(これは明示的なので最終的ですが)。

第三のオプションがありますあなたのニーズに応じて:初期化子ブロックを使用します。

class Super { 
    { 
    //this is the initializer block that is called before the corresponding constructors 
    //are called so it might or might not fit your needs 
    } 
} 

ここでは、すべての3つのオプションを組み合わせた例です:

static class Super { 
    { 
    //called before any of the Super constructors 
    System.out.println("Super initializer"); 
    } 

    private final void init() { 
    System.out.println("Super init method"); 
    } 

    public Super() { 
    System.out.println("Super common constructor"); 
    } 

    public Super(String name) { 
    this(); //needs to be the first statement if used 
    System.out.println("Super name constructor"); 
    init(); //can be called anywhere 
    } 
} 

static class Sub extends Super { 
    { 
    //called before any of the Sub constructors 
    System.out.println("Sub initializer"); 
    } 

    private final void init() { 
    System.out.println("Sub init method"); 
    } 

    public Sub() { 
    System.out.println("Sub common constructor"); 
    } 

    public Sub(String name) { 
    super(name); //needs to be the first statement if used, calls the corrsponding Super constructor 
    System.out.println("Sub name constructor"); 
    init(); //can be called anywhere 
    } 
} 

あなたが今new Sub("some name")を呼び出した場合、あなたが買ってあげます次の出力:

Super initializer 
Super common constructor 
Super name constructor 
Super init method 
Sub initializer 
Sub name constructor 
Sub init method 
3

Javaコンパイラは、基底クラスのコンストラクタへの呼び出しを確認する必要がありますので、あなたは、抽象基底クラスのコンストラクタに共通のコードを配置することができます:

abstract class BaseClass { 
    protected BaseClass(/*put arguments here*/) { 
     // Code that is common to all child classes 
    } 
} 
class ChildClassOne extends BaseClass { 
    public ChildClassOne(/*put arguments here*/) { 
     super(arg1, arg2, ...); 
     // More code here 
    } 
} 
1

あなたはクラスのインスタンスメソッドを宣言することができます

Class A{ 
    public A(){ 
    initialize(); 
    } 

    public void initialize(){ 
    //code goes here 
    } 
} 

このコンセプトは抽象クラスにも適用されます。

1

コンストラクタをチェーンすることができます。

public class Test { 

    public Test() { 
     // Common initialisations. 
    } 

    public Test(String stuff) { 
     // Call the one^
     this(); 
     // Something else. 
    } 

次に、共通コードを()コンストラクタに入れることができます。

0

代わりにInitializer block

Class A { 
    { 
    // initialize your instance here... 
    } 
    // rest of the class... 
} 

コンパイラは、いずれかのコンストラクタの前にイニシャライザコードが呼び出されていることを確認します。

しかし、これを使うのはちょっと躊躇します。おそらく他の選択肢がない(基底クラスにコードを置くなど)場合にのみ使用してください。

0

共通のコードを1つのコンストラクタに入れて、他のコンストラクタの最初の命令としてを呼び出すことができる場合は、Javaの慣用方法です。

ユースケースが複雑な場合は、コンシューマから特定のメソッドを呼び出すことができます。ただし、プライベート、ファイナル、またはスタティックの場合は(可)ユースケースの例は次のようになります。

class Test { 
    private final void init(int i, String str) { 
     // do common initialization 
    } 
    public Test(int i) { 
     String str; 
     // do complex operations to compute str 
     init(i, str); // this() would not be allowed here, because not 1st statement 
    } 

    public Test(int i, String str) { 
     init(i, str); 
    } 

} 
0

共通のメソッドを作成し、それをインスタンス変数に割り当てます。それを行う別の方法。

import java.util.List; 

public class Test { 
    int i = commonMethod(1); 

    Test() { 
     System.out.println("Inside default constructor"); 
    } 

    Test(int i) { 
     System.out.println("Inside argument Constructor "); 
    } 

    public int commonMethod(int i) { 
     System.out.println("Inside commonMethod"); 
     return i; 
    } 

    public static void main(String[] args) { 
     Test test1 = new Test(); 
     Test test2 = new Test(2); 

    } 
} 
関連する問題