Frage

Es tut mir leid, wenn dies eine doppelte oder zu elementar ist, aber wie mache ich eine Singleton-Klasse, die Unterklassen werden kann?

War es hilfreich?

Lösung

Steve Yegge hat eine amüsante Artikel über Singletons, die in diesem Zitat erwähnt Subklassen :

  

Dann gibt es die Subklassifizieren Sache.   Es ist fast unmöglich, eine Unterklasse   Singleton, und wenn du es schaffst, dann   Sie sollten verwendet haben ein nicht   Singleton in erster Linie. Sie   nicht noch wollen, dorthin zu gehen. Ich habe   ging Straßen, die ich nicht erzählen wagen.   Einfach so tun Sie es nicht tun, und   Sie finden sich erstaunliche Mengen speichern   von Schmerz.

Andere Tipps

Sie können in der Regel nicht in jedem nützlichen Sinne. Dies wäre ein weiterer Grund, nicht Singleton-Klassen zu verwenden.

Tatsächlich, ich glaube nicht, es ist möglich.

Sie machen eine Klasse Singleton durch den Konstruktor deklarieren (n) private werden. Aber wenn Sie dann versuchen, eine Unterklasse der Singleton-Klasse zu deklarieren, wird die Unterklassen-Konstruktor nicht in der Lage, die Erbauer der Oberklasse zu sehen ..., damit sie nicht zusammenstellen; z.

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

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

Sowohl die Sun JDK 1.6 und Eclipse Ganymede Compiler einem Kompilierungsfehler im Konstruktor B geben, zu dem Effekt, dass der No-args Konstruktor für A nicht sichtbar ist.

Sie können die Sichtbarkeit des private Konstrukteure erhöhen, aber dann gibt es nichts (abgesehen von gutem Sinne) jemand stoppen von mehreren Instanzen davon zu schaffen. Mit anderen Worten ist es nicht wirklich eine Singleton-Klasse mehr.

EDIT: Ich denke, eine koschere Alternative einen Baum von einem oder mehreren abstrakten (nicht-Singleton) Klassen mit den Methoden / Mitglieder zu definieren wäre, die Sie gemeinsam sein wollen, und dann mehrere Singleton-Klassen als Blattklassen definieren angemessen. Aber das ist nicht ein Singletonklasse Subklassen eine andere.

Wenn Sie Ihre Singleton wie folgt definiert:

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

Dann können Sie einfach tun:

public class NewSingleton extends Singleton {
}

Aber Sie werden nicht in der Lage sein, die privaten Methoden verwenden, so dass, wenn Sie die Singleton verwenden möchten werden Sie noch Singleton.getInstance(); anrufen müssen, so dass Sie nichts gewinnen, indem sie erstrecken.

Aber es gibt keinen Grund, warum Sie es nicht tun können.

Wenn Sie jetzt mehr Funktionen in die Singleton-Klasse hinzufügen möchten, dann können Sie inter Typ Aspekte von AspectJ verwenden und nur neue Methoden / Eigenschaften in den Singleton injizieren, die dann durch die Singleton verwendet werden könnten.

Singleton begrenzt Instanzen nicht die Vererbung. Nun - wie bereits darauf hingewiesen worden, es begrenzt Nützlichkeit der Vererbung und dann können Sie privaten Konstruktor entspannen verpackt oder geschützt (die man argumentieren kann singletoness des Singletons verringert) Aber was ist der Zweck

?

Wie andere schon geantwortet haben, sind die Verwendungen von Singleton Subklassifizieren klein. Wenn Sie ein Strategie-Muster im Rahmen eines Singleton benötigen, könnten Sie eine Schnittstelle und Delegierten auf eine Implementierung dieser Schnittstelle in der Singleton-Instanz definieren. Dadurch wird das Problem einer Schicht nach unten und macht es klar, warum Sie es tun möchte.

Um Ihre Frage zu beantworten; unter der Annahme, verwendet die Wahl für die jeweilige Unterklasse der Anwendung der Systemeigenschaften in zum Beispiel definiert ist, können Sie so etwas wie tun:

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: ungetesteten Code, fügen Sie die Ausnahmebehandlung, etc. :-) Btw, stellen Sie sicher, dass Ihre getInstance() Methode synchronisiert wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top