2

我毫不怀疑这个问题已经在这里被问过十几次了,但我就是找不到满意的答案。

我有一个类族,我只想通过这样的静态方法由抽象父类实例化(我在这里可能有错别字,我正在输入但没有尝试编译)。

public abstract class Papa {
    public static Papa newInstance() {
        String strClass = Papa.figureOutTheNameOfChildClassToInstantiate();
        Papa papa = (Papa) Class.forName(strClass).newInstance();
        return papa;
    }
    public abstract void doSomething();
    ...
}
public class Child extends Papa {
    public void doSomething() { /* Do something */ }
}

这或多或少是我现在所拥有的。我想做的是确保 Child 只能由工厂方法 Papa.newInstance() 实例化。我试图通过将 Child 的无参数构造函数设为私有来做到这一点,但是 Papa 无法实例化它。

所以,我的问题是,如何确保子实例仅由工厂方法 Papa.newInstance() 创建?

4

2 回答 2

3

如果您绝对肯定地想要强制执行此操作,请提供Papa一个受保护的构造函数,该构造函数采用 type 参数Xyzzy。在Xyzzy中创建一个受保护的内部类Papa。给它一个私有构造函数。现在,只能Papa创建Xyzzy. 由于您需要一个实例Xyzzy来调用Papa的构造函数,并且由于 的​​子类Papa必须从其构造函数中调用其构造函数,因此您需要一个实例Xyzzy来调用 的任何子类的构造函数Papa。因此,只能Papa调用其子类的构造函数。虽然Xyzzy什么都不做。

子类可能会泄漏它们的Xyzzy实例,这将允许其他代码调用子类构造函数。但是您也可以通过Xyzzy一次性使用来限制它,并且只能在单个静态工厂调用的上下文中进行。

但老实说,我不会打扰!

于 2012-06-18T12:30:10.050 回答
3

几个可能的选择:

  1. 使用子类构造函数的默认可见性并将它们放在与父类相同的包中。这样做的缺点是这些类可以由同一包中的任何其他类实例化,包括任何“兄弟”类。

  2. 将所有子类作为父类中的嵌套类。将它们标记为private static将使它们仅对父类可见。不幸的是,这也意味着所有类的代码都在同一个文件中......

于 2012-06-18T12:31:59.957 回答