Java 如何使其他类从单例类派生?

Java 如何使其他类从单例类派生?,java,singleton,Java,Singleton,如果这是一个重复的或太简单的类,我很抱歉,但是我如何创建一个可以子类化的单例类呢?从任何有用的意义上讲,您通常不能。这将是不使用单例类的另一个原因 如果您已将单身定义为: public class Singleton { private static Singleton instance; public static Singleton getInstance() { if (instance == null) { instance = new Singleton

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

从任何有用的意义上讲,您通常不能。这将是不使用单例类的另一个原因

如果您已将单身定义为:

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限制实例,而不是继承。正如已经指出的那样,它限制了继承的有用性,然后您可以将私有构造函数放松为打包或保护(您可能会认为这会减少单例的单例性),但目的是什么呢?

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

通过将类的构造函数声明为
private
,可以使类成为单例。但是,如果您试图声明单例类的子类,子类构造函数将无法看到超类的构造函数。。。所以他们不会编译;e、 g

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

public class B () {
    private B() { }
}
Sun JDK 1.6和Eclipse Ganymede编译器都在构造函数B中给出了一个编译错误,结果是a的无参数构造函数不可见

您可以增加
私有
构造函数的可见性,但是没有什么(除了良好的感觉)可以阻止某人创建它的多个实例。换句话说,它不再是一个真正的单例类


编辑:我想一个更合适的选择是定义一个或多个抽象(非单例)类的树,其中包含您希望通用的方法/成员,然后根据需要将多个单例类定义为叶类。但这不是一个单例类对另一个单例类的子类。

史蒂夫·耶格(Steve Yegge)有一个有趣的单例类,在这段引文中提到了子类化:

然后是子类化。 几乎不可能将a分为子类 单身,如果你能做到,那么 你不应该用一个 首先是单身。你 我甚至不想去那里。我已经 走着我不敢重述的路。 假装你做不到,然后 你会为自己省下惊人的钱 疼痛的感觉


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

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

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()
方法是同步的。

为什么要进行向下投票?这似乎是一个合理的问题?也许选民最近吃了晚饭,现在感觉很饱,所以“消化”的参考不吸引人…?抱歉@Alex。当你发表的时候,我把你的笑话搞糟了。我没有得到“YouTube Yes”的下注——那是不是一些新的特效药?它汇编了。。。我是个白痴,竟然把时间浪费在创建两个测试类上。所以它确实(至少-没有参数构造函数)哦,胡说八道-‘浪费’,这不是为我编译的。(eclipse)编译器说“隐式超级构造函数A()不可见。必须显式调用另一个构造函数。”这是在类B的构造函数中,其中B扩展了A,并且A和B都有显式的私有无参数构造函数。如果你想这样读它,那么是的,它是否。或者你可以读它,然后看到答案是肯定的,但是你仍然不应该尝试,你可能想评估一下为什么你首先要使用单例。