如何在构造之后执行子类的继承初始化方法?

时间:2017-06-26 05:44:17

标签: java class inheritance constructor initialization

请考虑以下代码:

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()在子类的字段初始化并显示[]后正确运行。无论如何,它看起来仍然非常hacky,起初可能会令人困惑。除了我所做的以外,还有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

这个想法在我看来是有缺陷的,因为你只是使用configure方法替代子构造函数。它无论如何都没用。

为什么首先需要配置?所以子类可以覆盖你说的。但他们已经可以覆盖构造函数,那么重点是什么?

find . -type f -name "*.txt" -exec grep -lis needle {} +