は、以下のコードを検討:建設後にサブクラスの継承された初期化メソッドを実行するには?
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();
}
}
サブクラスのフィールドが初期化されていると[]
が表示された後に正しく動作します。それにもかかわらず、それはまだかなりハッキーとおそらく最初は混乱しているようです。私がやったことの他にこれを行う良い方法がありますか?
スーパークラスのコンストラクタから 'configure();'を削除するだけですか? – Yahya
@Yahyaユーザーは、異なるユースケースに対してどちらのクラスに対してもconfigure()を実装して使用できるようにしたいと考えています。 – kmecpp
Commandクラスが抽象的であると見ると、configureのメソッドも抽象的であると理解できないでしょうか? – MartinByers