我毫不怀疑这已经被问了十几次,但我找不到满意的答案。
我有一个类的系列,我只想通过这样的静态方法由抽象父类实例化(我可能在这里打字错误,我在打字而不试图编译)。
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()创建?
答案 0 :(得分:3)
如果你绝对,肯定地想要强制执行此操作,那么给Papa
一个受保护的构造函数,该构造函数接受Xyzzy
类型的参数。在Xyzzy
中将Papa
设为受保护的内部类。给它一个私有的构造函数。现在,只有Papa
才能生成Xyzzy
的实例。由于您需要Xyzzy
的实例来调用Papa
的构造函数,并且由于Papa
的子类必须从其构造函数调用其构造函数,因此您需要Xyzzy
的实例调用Papa
的任何子类的构造函数。因此,只有Papa
可以调用其子类的构造函数。即使Xyzzy
没有做任何事情。
子类可能泄漏其Xyzzy
实例,这将允许其他代码调用子类构造函数。但是你也可以通过Xyzzy
一次性使用来限制它,并且只能在单个静态工厂调用的上下文中使用。
但说实话,我不会打扰!
答案 1 :(得分:3)
有几种可能的选择:
使用子类构造函数的默认可见性,并将它们放在与父类相同的包中。这样做的缺点是,这些类可以由同一个包中的任何其他类实例化,包括任何“兄弟”类。
在父类中将所有子类设为nested classes。将它们标记为private static
将使它们仅对父类可见。不幸的是,这也意味着在同一个文件中包含所有类的代码......