如何使其他类派生自单例类?

我很抱歉,如果这是重复或太基础,但我如何创建一个可以被子类化的单例类?

史蒂夫·叶格(Steve Yegge)有一篇关于单身人士的有趣文章 ,提到了这篇引文中的子类:

然后是子类化的东西。 将Singleton子类化几乎是不可能的,如果你管理它,那么你不应该首先使用Singleton。 你甚至不想去那里。 我走过了一条我不敢讲述的道路。 只是假装你做不到,你会为自己节省大量的痛苦。

在任何有用的意义上,你通常不能。 这将是不使用Singleton类的另一个原因。

实际上,我认为这是不可能的。

您通过将其构造函数声明为private来创建类单例。 但是如果你试图声明你的单例类的子类,那么子类构造函数将无法看到超类的构造函数……所以它们不会编译; 例如

 public class A () { private A() { } } public class B () { private B() { } } 

Sun JDK 1.6和Eclipse Ganymede编译器都在构造函数B中给出了编译错误,导致A的no-args构造函数不可见。

您可以提高private构造函数的可见性,但是除了良好意义之外没有任何东西阻止某人创建它的多个实例。 换句话说,它不再是真正的单身人士课程了。

编辑:我想一个犹太替代方案是使用您想要共同的方法/成员定义一个或多个抽象(非单例)类的树,然后根据需要将多个单例类定义为叶类。 但这不是一个单独的类inheritance另一个。

如果您已将单身人士定义为:

 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可以使用它们。

Singleton限制实例而不是inheritance。 好吧 – 正如已经指出的那样它限制了inheritance的有用性,然后你可以放松私有构造函数来打包或保护(你可能会认为减少单例的单例)但是目的是什么?

正如其他人已经回复的那样,单例子类的使用很少。 如果在单例的上下文中需要策略模式,则可以在单例实例中定义接口并委托给该接口的实现。 这会将问题向下移动一层,并使您更清楚为什么要这样做。

回答你的问题; 假设您的应用程序使用的特定子类的选择在例如系统属性中定义,您可以执行以下操作:

 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; } 

免责声明:未经测试的代码,添加exception处理等:-)顺便说一下,确保你的getInstance()方法是同步的。