是否可以将继承应用于单例类?

2022-09-01 14:15:01

今天我在面试中遇到了一个问题。是否可以在单例类上应用继承概念?我说由于构造函数是私有的,我们不能扩展该单例类。

接下来,他要求我对该单例类应用继承。因此,我将单例构造函数作为受保护的,认为子构造函数也受到保护。但是我错了,孩子可以有一个等于或高于这个的修饰符。

所以,我请他举一个真实的例子来说明这种情况。他无法给我一个,说我不能问问题,并希望我告诉这种情况是否可能。

我有点茫然。我的问题是,

  • 这可能吗?
  • 即使有可能,它有什么用呢?
  • 什么现实世界的场景需要这样的使用?

答案 1

引用圣经

当 [...] 唯一实例应可通过子类化进行扩展,并且客户端应该能够在不修改其代码的情况下使用扩展实例时,请使用 Singleton 模式。

单例模式有几个好处: [...]3. 允许优化操作和代表。Singleton 类可能是子类,并且很容易使用此扩展类的实例配置应用程序。可以使用运行时所需类的实例配置应用程序。

至于如何实现这一点:这本书提出了几种方法,其中最复杂的是一个注册表,其中按名称查找实例。


答案 2

是的,这在技术上是可行的,因为单例是一种设计模式,而不是可能具有继承限制的语言构造。我只是在子类中重新实现该方法(见下文)。public [Object] getInstance()

而且,是的,单例也可以从继承中受益,因为它们可能与其他单例共享相似但不识别的行为。

public class ParentSingleton {

    private static ParentSingleton instance;

    protected ParentSingleton() {
    }

    public static synchronized ParentSingleton getInstance() {
       if (instance == null) {
          instance = new ParentSingleton();
       }

       return instance;
    }

    public int a() {
       // (..)
    }       
}

public class ChildSingleton extends ParentSingleton {

    private static ChildSingleton instance;

    public static synchronized ParentSingleton getInstance() {
       if (instance == null) {
          instance = new ChildSingleton();
       }

       return instance;
    }       
}

编辑:正如Eyal在下面的评论中指出的那样,超类中的构造函数必须受到保护(而不是私有),否则子类将不可见,代码甚至无法编译。


推荐