单例继承

16

我该如何从单例类继承到其他需要相同功能的类中呢?是否可以采用这种方式实现?

4个回答

16

Jon Skeet曾经写过这方面的内容,可以参考这里。虽然使用嵌套内部类不是很理想,但通过Singleton可以实现继承的一些好处。它并没有无限的可扩展性,只是一种让Singleton在运行时选择自己的实现技术。

实际上,从Singleton进行继承并没有太多意义,因为Singleton模式的一部分是实例管理。一旦你已经拥有了一个基类型的实例,就太晚了去在派生类型中覆盖它的任何部分。即使你可以这样做,我认为它可能会导致设计难以理解,也更加难以测试和维护。


4
你可以继承单例并使用模板(C ++)或泛型(C#.NET)进行“重用”或一些微调。
我在我的博客(www.devartplus.com)中发布了一系列关于这个主题的文章:
1)在C#.NET中基本的单例继承
2)在C#.NET中线程安全的单例继承
3)C ++中的几个单例实现
欢迎访问这些链接,并与大家分享您的意见。祝好运。

1
有几种解决方案使用内部类和反射(其中一些在其他答案中提到)。然而,我认为所有这些解决方案都涉及客户端和派生类之间的紧密耦合。
以下是一种方法,允许客户端只依赖于基类,并且可以进行扩展。
基类类似于通常的实现,除了我们将其定义为抽象类(如果可以实例化基类,则也可以像普通单例一样定义它)。
public abstract class Animal {
    protected static Animal instance;
    public static Animal theInstance(){
        assert instance != null : "Cannot instantiate an abstract Animal";
        return instance;
    }
    abstract void speak();
}

任何子类型都有自己的theInstance方法(您无法覆盖静态方法)。例如:
public class Dog extends Animal{
    protected Dog(){}

    public static Animal theInstance(){
        if (instance == null){
            instance = new Dog();
        }
        return instance;
    }

    @Override
    void speak() {
        System.out.println("Wouf");
    }
}

在主类中,您将编写Dog.theInstance(),任何后续客户端都会调用Animal.theInstance()。这样,客户端可以完全独立于派生类,并且可以添加新的子类而无需重新编译客户端(开闭原则)。

0

有人可以随便纠正我,但是我理解的方式,并且曾经因此出现过错误:

public class BaseClass
{
  protected static List<string> ListOfSomething { get; set; }
}

public class ChildClass
{
  protected static List<int> ListOfSomethingElse { get; set; }
}

public class AnotherChildClass
{
  protected static List<int> ListOfSomethingElse { get; set; }
}

这两个子类会共享同一个ListOfSomething,它们不会拥有自己的副本。相同的静态对象将在所有子类中共享。 这是单例行为和继承的蜕变。正如Silky所说...你只是不应该这样做,否则你可能会遇到类似的问题

如果你不是在谈论这种情况...我不确定你在谈论什么单例模式,举个例子会很有帮助,因为单例有很多特定用途。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接