2017-06-26 1 views
1

は、以下のコードを検討:建設後にサブクラスの継承された初期化メソッドを実行するには?

public abstract class Command { 

    public Command() { 
     configure(); 
    } 

    public void configure() { 
    } 

} 


public abstract class ComplexCommand extends Command { 

    private ArrayList<String> commands = new ArrayList<>(); 

    @Override 
    public void configure() { 
     System.out.println(commands); 
    } 

} 

configure()方法は、コマンドの属性を変更するためにコマンドまたはComplexCommandいずれかのサブクラスによって実装されることを意図し、したがって目的の機能がでconfigure()方法を実行するようになっています(コマンド変数は初期化されています)。ただし、この例でnew ComplexCommand()を呼び出すと、nullがコンソールに出力されます。私が間違っている場合は私を修正しますが、サブクラスのフィールドが初期化される前に、サブクラスのコンストラクタに暗黙のうちにsuper()が実行されるためです。ここで

は、これらのクラスの使用方法の例です。この遊ん

public class MyTestCommand extends Command { 

    @Override 
    public void configure() { 
     setUsage("Usage: /test <target>"); 
     setDescription("This is a test command"); 
    } 

} 

、私はこの問題を回避する1つの方法を考え出すでしたが、誰もがよりよい解決策を持っている場合、私は思ったんだけど。私の修正は、親コンストラクタをオーバーライドすることでした。これは、親からのconfigure()の実行を有効/無効にしてから、代わりに子から実行することです。この例configure()

public abstract class Command { 

    public void configure() { 
    } 

    public Command() { 
     configure(); 
    } 

    protected Command(boolean configure) { 
     if (configure) { 
      configure(); 
     } 
    } 

} 

public abstract class ComplexCommand extends Command { 

    private ArrayList<String> commands = new ArrayList<>(); 

    @Override 
    public void configure() { 
     System.out.println(commands); 
    } 

    public ComplexCommand() { 
     super(false); 
     configure(); 
    } 

} 

サブクラスのフィールドが初期化されていると[]が表示された後に正しく動作します。それにもかかわらず、それはまだかなりハッキーとおそらく最初は混乱しているようです。私がやったことの他にこれを行う良い方法がありますか?

+0

スーパークラスのコンストラクタから 'configure();'を削除するだけですか? – Yahya

+0

@Yahyaユーザーは、異なるユースケースに対してどちらのクラスに対してもconfigure()を実装して使用できるようにしたいと考えています。 – kmecpp

+0

Commandクラスが抽象的であると見ると、configureのメソッドも抽象的であると理解できないでしょうか? – MartinByers

答えて

1

このコンセプトは、あなたがsubconstructorの代わりにconfigureメソッドを使っているだけなので、私の意見では間違っています。それは決して役に立たない。

なぜ最初に設定する必要がありますか?したがって、サブクラスはそれをオーバーライドすることができます。しかし、彼らはすでにコンストラクタをオーバーライドできるので、何がポイントですか?

public abstract class Command { 

    public Command() { 
     // Do things to initialize Command 
    }  
} 

public abstract class ComplexCommand extends Command { 

    private ArrayList<String> commands; 

    public ComplexCommand() { 
     super(); 
     // Do things to initialize ComplexCommand 
     this.commands = new ArrayList<>(); 
     System.out.println(this.commands); 
    }  
} 

public class MyTestCommand extends Command { 

    public MyTestCommand() { 
     super(); 
     setUsage("Usage: /test <target>"); 
     setDescription("This is a test command"); 
    }  
} 
+0

これは私がやっていることのために、感謝します。私はコードをリファクタリングしている間にコンストラクタを削除することにも巻き込まれてしまいました。 – kmecpp

+0

@kmecppそして私は何を言っていたのですか? – Yahya

+0

@ Yahyaあなたはスーパークラスのコンストラクタからconfigure()を削除することを提案しました。私がこれをしていれば、Commandを使った実装は、今まで実行されたconfigureメソッドを実行しませんでした。 – kmecpp

関連する問題