gpt4 book ai didi

java - 在任何派生类的构造函数之后运行方法

转载 作者:IT老高 更新时间:2023-10-28 20:40:43 25 4
gpt4 key购买 nike

假设我有一个 Java 类

abstract class Base {
abstract void init();
...
}

而且我知道每个派生类在构建后都必须调用 init()。当然,我可以简单地在派生类的构造函数中调用它:

class Derived1 extends Base {
Derived1() {
...
init();
}
}

class Derived2 extends Base {
Derived2() {
...
init();
}
}

但这严重违反了“不要重复自己”的原则(并且会有很多 Base 的子类)。当然,init() 调用不能进入 Base() 构造函数,因为它会执行得太早。

任何想法如何绕过这个问题?我也很高兴看到 Scala 解决方案。

更新:这是工厂方法方法的通用版本:

interface Maker<T extends Base> {
T make();
}

class Base {
...
static <T extends Base> T makeAndInit(Maker<T> maker) {
T result = maker.make();
result.init();
return result;
}
}

更新2:这个问题基本上是“你如何为构造函数使用模板方法”?答案似乎是,“你可以,但这是个坏主意”。所以我可以做一个模板工厂(模板方法+抽象工厂)。

最佳答案

避免这种情况。如果你这样做,任何扩展你的 DerivedX 类的类都可能决定也调用 init() 从而使对象处于不一致的状态。

一种方法是让您的类的客户端手动调用 init() 方法。有一个 initialized 字段,如果没有它调用任何需要初始化的方法,则抛出 IllegalStateExcepion

更好的方法是使用静态工厂方法而不是构造函数:

public Derived2 extends Base {
public static Derived2 create() {
Derived2 instance = new Dervied2();
instance.init();
return instance;
}
}

更新:正如您在更新中建议的那样,您可以通过 Builder到一个静态工厂方法,它将调用实例上的 init()。但是,如果您的子类很少,我认为这过于复杂了。

关于java - 在任何派生类的构造函数之后运行方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2906958/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com