2009-10-22 36 views
5

对不起,如果这是一个重复或太简单,但我该如何做一个可以分类的单例类?如何让其他类从单例类派生出来?

+1

为什么downvote?这似乎是一个合法的问题? – 2009-10-22 05:03:20

+1

也许最近downvoter吃晚饭,目前感觉饱满,所以“饮食”的参考感觉没有吸引力......? – 2009-10-22 05:09:20

+0

对不起@亚历克斯。当你发布它时,我毁了你的笑话。 – 2009-10-22 05:10:07

回答

11

史蒂夫·耶格有一个有趣的article关于提到了这句话继承单身:

然后是子类的东西。 几乎不可能继承一个 单身人士,如果你管理它,那么 你不应该首先使用单身人士。你 不要甚至想去那里。我有 走的道路,我不敢重述。 只是假装你不能这样做,而且你会为自己节省惊人的数额 的痛苦。

+0

所以答案是“否”? – unj2 2009-10-22 15:37:12

+1

如果你想这样阅读,那么是的,这不是。或者你可以阅读它,看到答案是肯定的,但你仍然不应该尝试,你可能想要评估为什么你要使用单例。 – 2009-10-22 15:59:40

5

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

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

1

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

3

其实我认为这是不可能的。

通过声明其构造函数为private来创建一个类的单例。但是如果你尝试声明你的单例类的子类,那么子类的构造函数将不能够看到超类的构造函数......所以它们不会被编译;例如

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

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

与太阳JDK 1.6和Eclipse编译木卫三给出一个编译错误,在构造B,以对于一个无参数的构造是不可见的效果。

你可以增加private构造函数的可见性,但是除此之外没有任何东西可以阻止某人创建它的多个实例。换句话说,它不再是一个单身人士课程。

编辑:我想犹太教的另一种选择是定义一个或多个抽象(非单一)类的树与您想要常见的方法/成员,然后将多个单例类定义为叶类作为适当的。但这不是一个单独类别的另一个子类别。

+0

它编译...我很笨,足以让我在创建2个测试课程的时候腰缠万贯。所以它确实(至少 - 没有参数构造函数) – Bostone 2009-10-22 06:01:09

+0

哦牛 - '废物'是 – Bostone 2009-10-22 06:02:16

+0

牛与这个有什么关系? :-) – 2009-10-22 06:24:32

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