【发布时间】:2017-11-28 22:29:41
【问题描述】:
考虑以下代码:
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() 方法旨在由 Command 或 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");
}
}
玩弄这个,我确实想出了一种解决问题的方法,但我想知道是否有人有更好的解决方案。我的解决方法是通过创建一个允许/禁用从父级执行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() 在子类的字段已初始化并显示 [] 后正确运行。无论如何,它看起来仍然很老套,一开始可能会令人困惑。除了我所做的之外,还有更好的方法吗?
【问题讨论】:
-
什么你不只是从超类的构造函数中删除
configure();? -
@Yahya 我希望用户能够针对不同的用例为任一类实现和使用 configure()。
-
既然您的 Command 类是抽象的,那么 configure 方法也是抽象的不是很有意义吗?
标签: java class inheritance constructor initialization