如果这是重复或过于简单,我很抱歉,但如何创建可以进行子类化的单例类?
答案 0 :(得分:11)
史蒂夫·叶格(Steve Yegge)有一个有趣的article关于单身人士,他们在这句话中提到了子类:
然后是子类化的东西。 子类化几乎是不可能的 单身,如果你管理它,那么 你不应该使用 单身人士首先。您 不要甚至想去那里。我有 走路,我不敢讲述。 只是假装你不能这样做,并且 你会节省惊人的金额 痛苦。
答案 1 :(得分:5)
在任何有用的意义上,你通常都不能。这将是不使用Singleton类的另一个原因。
答案 2 :(得分:3)
实际上,我认为不可能。
通过将其构造函数声明为private
来创建类单例。但是如果你试图声明你的单例类的子类,那么子类构造函数将无法看到超类的构造函数......所以它们不会编译; e.g。
public class A () {
private A() { }
}
public class B () {
private B() { }
}
Sun JDK 1.6和Eclipse Ganymede编译器都在构造函数B中给出了编译错误,导致A的no-args构造函数不可见。
您可以提高private
构造函数的可见性,但是除了良好意义之外没有任何东西阻止某人创建它的多个实例。换句话说,它不再是单身人士课程了。
编辑:我想犹太教的替代方案是使用您想要共同的方法/成员定义一个或多个抽象(非单例)类的树,然后将多个单例类定义为叶类适当。但这不是一个单独的类继承另一个。
答案 3 :(得分:1)
如果您已将单身人士定义为:
public class Singleton {
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
private Singleton() {
}
}
然后你可以这样做:
public class NewSingleton extends Singleton {
}
但是,你将无法使用私有方法,所以如果你想使用单身,你仍然需要调用Singleton.getInstance();
,这样你就不会通过扩展它来获得任何东西。
但是,没有理由不能这样做。
现在,如果你想为Singleton类添加更多函数,那么你可以使用AspectJ中的类型间方面,只需将新方法/属性注入Singleton,然后Singleton就可以使用它。
答案 4 :(得分:1)
Singleton限制实例而不是继承。好吧 - 正如已经指出的那样它限制了继承的有用性,然后你可以放松私有构造函数来打包或保护(你可能会认为它会减少单例的单例)但是目的是什么?
答案 5 :(得分:0)
正如其他人已经回复的那样,单例子类的使用很少。如果在单例的上下文中需要策略模式,则可以在单例实例中定义接口并委托给该接口的实现。这会将问题向下移动一层,并使您更清楚为什么要这样做。
回答你的问题;假设您的应用程序使用的特定子类的选择在例如系统属性中定义,您可以执行以下操作:
public static synchronised Singleton getInstance() {
if (instance == null) {
String clsName = System.getProperties().getProperty("singleton.class");
if (className == null || 0 == clasName.length()) {
instance = new Singleton();
} else {
Class cls = Class.forName(clsName);
instance = (Singleton) cls.newInstance();
}
}
return instance;
}
免责声明:未经测试的代码,添加异常处理等:-)
顺便说一句,确保您的getInstance()
方法已同步。