Pergunta

Lamento se este é um duplicado ou muito elementar, mas como posso fazer uma única classe que pode ser uma subclasse?

Foi útil?

Solução

Steve Yegge tem uma divertida href="http://steve.yegge.googlepages.com/singleton-considered-stupid" artigo sobre singletons que menciona Subclassing nesta citação :

Depois, há a coisa subclasses. É quase impossível para subclasse um Singleton, e se você conseguir isso, então Você não deveria ter vindo a utilizar um Singleton em primeiro lugar. Vocês Não até quero ir para lá. Eu tenho andou estradas que não me atrevo a recontagem. Basta fingir que você não pode fazê-lo, e você vai salvar a si mesmo quantidades surpreendentes de dor.

Outras dicas

Você geralmente não pode, em qualquer sentido útil. Este seria mais um motivo para não usar classes Singleton.

Na verdade, eu não acho que isso é possível.

Você faz um singleton classe declarando seu construtor (s) a ser private. Mas se você, em seguida, tentar declarar uma subclasse de sua classe singleton, a subclasses construtor não será capaz de ver os construtores da superclasse ... de modo que não irá compilar; por exemplo.

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

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

Tanto o Sun JDK 1.6 e Eclipse Ganymede compilador dar uma compilação de erro no construtor B, no sentido de que o construtor sem argumentos para um não é visível.

Você poderia aumentar a visibilidade dos construtores private, mas então não há nada (além de bom senso) parar alguém de criar várias instâncias do mesmo. Em outras palavras, não é realmente uma classe singleton mais.

EDIT: Eu acho que uma alternativa kosher seria definir uma árvore de um ou mais abstratos (não únicos) classes com os métodos / membros que deseja ser comum, e, em seguida, definir várias classes únicas como um classes folha como apropriada. Mas isso não é uma única classe subclasse outro.

Se você tiver definido o seu singleton como:

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

Em seguida, você pode apenas fazer:

public class NewSingleton extends Singleton {
}

Mas, você não será capaz de usar os métodos privados por isso, se você quiser usar o singleton você ainda precisará Singleton.getInstance(); chamada para que você não ganha nada, estendendo-o.

Mas, não há nenhuma razão porque você não pode fazê-lo.

Agora, se você quiser adicionar mais funções para a classe Singleton, em seguida, você pode usar os aspectos inter-tipo de AspectJ e apenas injetar novos métodos / propriedades para o Singleton que poderia então ser utilizados pelo Singleton.

Singleton limita instâncias que não a herança. Bem - como já foi assinalado que limita a utilidade da herança e, em seguida, você pode relaxar construtor privado para embalado ou protegido (que você pode argumentar diminui singletoness do Singleton) Mas qual é a finalidade

?

Como outros já respondeu, os usos de subclasses singleton são pequenos. Se você precisa de um padrão de estratégia no contexto de um singleton, você pode definir uma interface e delegado para uma implementação dessa interface na instância singleton. Isso move a camada de um problema para baixo e torna mais claro por que você iria querer fazê-lo.

Para responder à sua pergunta; assumindo a escolha para a subclasse particular, seus usos de aplicação é definido em, por exemplo, as propriedades do sistema, você pode fazer algo como:

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: código não testado, tratamento de exceção add, etc :-) Btw, verifique se o método getInstance() é sincronizado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top