是否可以将inheritance应用于Singleton类?

今天我在采访中遇到了一个问题。 是否可以在Singleton类上应用inheritance概念? 我说因为构造函数是私有的,所以我们不能扩展那个Singleton类。

他问我的下一件事是在Singleton类上应用inheritance。 因此,我将Singleton的构造函数视为受保护的思想,即child的构造函数也受到保护。 但我错了,孩子可以有一个等于或高于此的修饰符。

所以,我让他给出一个关于这种情况的真实世界的例子。 他无法给我一个,并说我无法提问,并希望我告诉他们这种情况是否可能。

我有点空白。 我的问题是,

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

引用圣经 :

当单个实例应该通过子类化可扩展时使用Singleton模式,并且客户端应该能够使用扩展实例而无需修改其代码。

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

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

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

而且,是的,单身人士也可以从inheritance中受益,因为他们可能与其他单身人士分享相似但不具有识别性的行为。

 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在下面的评论中指出的那样,超类中的构造函数必须被保护(而不是私有),否则子类不可见,代码甚至无法编译。

您可以使用一组公共属性和方法创建一个抽象基类,然后创建一些子类作为单例类。 这是“以一种有用的方式应用inheritance概念”。

但是你不能做的是创建一个严格实现的单例类的子类。 如果将singleton类构造函数声明为private ,则子类将无法编译。 如果您使用其他访问权限声明它,则可以在另一个类中使用构造函数来创建多个实例…因此,它不是严格意义上的单例。 如果将单例声明为abstract ,则根本无法实例化…因此它不是单例。

它“可能”真的一起破解任何东西,但在这种情况下它并不是真的可取。 没有真正的理由将单例模式与inheritance一起使用,它并不意味着它。

私有构造函数对该单例类的其他内部类是可见的。 所以是的,从技术上讲,具有私有构造函数的单例类可以通过其内部类进行扩展。 但为什么你会这样做的事情超出我的范围。

下面是GOF中关于创建具有inheritance的单例的单例模式的一种实现。 这里应该修改父类以添加新的派生类。 环境变量可用于实例化适当的派生类构造函数。

 Mainfile – 1 #include  #include  #include "Singleton.h" using namespace std; int main(){ Singleton::instant().print(); cin.get(); } Singleton.h #pragma once #include  using std::cout; class Singleton{ public: static Singleton & instant(); virtual void print(){cout<<"Singleton";} protected: Singleton(){}; private: static Singleton * instance_; Singleton(const Singleton & ); void operator=(const Singleton & ); }; Singleton.cpp #include "Singleton.h" #include "Dotted.h" Singleton * Singleton::instance_ = 0; Singleton & Singleton::instant(){ if (!instance_) { char * style = getenv("STYLE"); if (style){ if (strcmp(style,"dotted")==0) { instance_ = new Dotted(); return *instance_; } else{ instance_ = new Singleton(); return *instance_; } } else{ instance_ = new Singleton(); return *instance_; } } return *instance_; } Dotted.h #pragma once class Dotted; class Dotted:public Singleton{ public: friend class Singleton; void print(){cout<<"Dotted";} private: Dotted(){}; }; 

我猜这不是他不想要的,但如果你想获得技术,你也可以提到Singleton是一种模式,而不是一种实现。 使用类构造函数不是获得Singleton的唯一方法,您可以让工厂强制执行该模式,在这种情况下,您可以使用与其他类完全相同的方式inheritance。

你可以使构造函数包私有。 这样,包外的任何类都不能实例化Singleton类,但派生类可以调用上层类构造函数。

但是,正如其他人所说,这是不可取的。

顺便说一下愚蠢的面试问题。