How do I make other classes derive from a singleto

2020-07-16 09:26发布

I am sorry if this is a duplicate or too elementary, but how do I make a singleton class that can be subclassed?

6条回答
倾城 Initia
2楼-- · 2020-07-16 09:37

You generally can't, in any useful sense. This would be yet another reason to not use Singleton classes.

查看更多
来,给爷笑一个
3楼-- · 2020-07-16 09:48

Steve Yegge has an amusing article about singletons that mentions subclassing in this quote:

Then there's the subclassing thing. It's almost impossible to subclass a Singleton, and if you manage it, then you shouldn't have been using a Singleton in the first place. You don't even want to go there. I've walked roads that I dare not recount. Just pretend you can't do it, and you'll save yourself amazing amounts of pain.

查看更多
唯我独甜
4楼-- · 2020-07-16 09:55

Singleton limits instances not the inheritance. Well - as already been pointed out it limits usefulness of inheritance and then you can relax private constructor to packaged or protected (which you may argue diminishes singletoness of the singleton) But what is the purpose?

查看更多
在下西门庆
5楼-- · 2020-07-16 09:57

If you have defined your singleton as:

public class Singleton {
  private static Singleton instance;
  public static Singleton getInstance() {
     if (instance == null) {
       instance = new Singleton();
     }
     return instance;
  }
  private Singleton() {
  }
}

Then you can just do:

public class NewSingleton extends Singleton {
}

But, you won't be able to use the private methods so if you want to use the singleton you will still need to call Singleton.getInstance(); so you gain nothing by extending it.

But, there is no reason why you can't do it.

Now, if you want to add more functions to the Singleton class then you can use inter-type aspects from AspectJ and just inject new methods/properties into the Singleton which could then be used by the Singleton.

查看更多
放荡不羁爱自由
6楼-- · 2020-07-16 09:59

Actually, I don't think it is possible.

You make a class singleton by declaring its constructor(s) to be private. But if you then try to declare a subclass of your singleton class, the subclasses constructor wont be able to see the constructors of the superclass ... so they won't compile; e.g.

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

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

Both the Sun JDK 1.6 and Eclipse Ganymede compiler give a compilation error in the constructor B, to the effect that the no-args constructor for A is not visible.

You could increase the visibility of the private constructors, but then there is nothing (apart from good sense) stopping someone from creating multiple instances of it. In other words it is not really a singleton class anymore.

EDIT: I guess a kosher alternative would be to define a tree of one or more abstract (non-singleton) classes with the methods / members that you want to be common, and then define multiple singleton classes as a leaf classes as appropriate. But that is NOT one singleton class subclassing another one.

查看更多
家丑人穷心不美
7楼-- · 2020-07-16 10:00

As others have replied already, the uses of singleton subclassing are small. If you need a strategy pattern in the context of a singleton, you could define an interface and delegate to an implementation of that interface in the singleton instance. This moves the problem one layer down and makes it more clear why you would want to do it.

To answer your question; assuming the choice for the particular subclass your application uses is defined in for instance the system properties, you can do something like:

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

Disclaimer: untested code, add exception handling, etc :-) Btw, make sure your getInstance() method is synchronised.

查看更多
登录 后发表回答