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

时间:2009-10-22 04:57:25

标签: java singleton

如果这是重复或过于简单,我很抱歉,但如何创建可以进行子类化的单例类?

6 个答案:

答案 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()方法已同步。