Действительно ли возможно применить наследование к Singleton-классу?

Сегодня я столкнулся с одним вопросом в интервью. Действительно ли возможно применить понятие наследования на Singleton-классы? Я сказал, так как конструктор является частным, мы не можем расширить тот Singleton-класс.

Следующая вещь он спросил меня, состоит в том, чтобы применить наследование на тот Singleton-класс. Так, я сделал конструктора Singleton, как защищено думающего, что конструктор ребенка также имеет быть защищенным. Но я был неправ, что у ребенка может быть модификатор, или равный или выше, чем это.

Так, я попросил, чтобы он дал пример реального мира на таком случае. Он не смог дать мне один и сказал, что я не могу задать вопросы и хотел, чтобы я сказал, возможен ли этот сценарий или нет.

Я пошел вид пробела. Мой вопрос здесь,

  • Действительно ли это возможно?
  • Даже если возможно, каково использование его?
  • Какой сценарий реального мира потребовал бы такого использования?
21
задан bragboy 11 May 2010 в 19:08
поделиться

8 ответов

Цитирование библии :

Используйте шаблон Singleton, когда [...] единственный экземпляр должен быть расширяемым путем создания подклассов, а клиенты должны иметь возможность использовать расширенный экземпляр {{1 }} без изменения их кода.

Шаблон Singleton имеет несколько преимуществ: [...] 3. Позволяет уточнять операции и представление. Класс Singleton может быть подклассом, и легко настроить приложение с помощью экземпляра этого расширенного класса. Вы можете настроить приложение с помощью {{ 1}} экземпляр класса, который вам нужен во время выполнения .

Что касается того, как это реализовать: в книге предлагается несколько способов, наиболее сложным из которых является реестр, в котором экземпляры ищутся по имени.

12
ответ дан 29 November 2019 в 20:32
поделиться

Я предполагаю, что это не то, что он искал, но если вы хотите получить техническую информацию, вы также можете упомянуть, что синглтон - это шаблон, а не реализация. Возиться с конструктором класса - это не единственный способ получить синглтон, у вас может быть фабрика, применяющая шаблон, и в этом случае вы можете использовать наследование точно так же, как и с другими классами.

1
ответ дан 29 November 2019 в 20:32
поделиться

Вы можете сделать пакет конструктора закрытым. Таким образом, никакие классы вне пакета не могут создавать экземпляр класса Singleton, но производные классы могут вызывать конструктор верхнего класса.

Но, как говорили другие, это действительно не рекомендуется.

Между прочим, глупый вопрос об интервью.

-2
ответ дан 29 November 2019 в 20:32
поделиться

Да , это технически возможно, поскольку синглтон - это шаблон проектирования, а не языковая конструкция, которая может иметь ограничения наследования. Я бы просто переопределил метод 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;
    }       
}

РЕДАКТИРОВАТЬ : как указал Эял в своих комментариях ниже, конструктор в суперклассе должен быть защищенным (а не закрытым), иначе он не будет виден дочерним классам, и код даже не будет компилировать.

12
ответ дан 29 November 2019 в 20:32
поделиться

Вы можете создать абстрактный базовый класс с кучей общих атрибутов и методов, а затем создать несколько подклассов в виде синглтонов. Это и есть "применение концепции наследования" ... полезным способом.

Но чего вы не можете сделать, так это создать подкласс строго реализованного класса singleton. Если вы объявите конструктор класса singleton как private, подкласс не скомпилируется. Если вы объявите его с другим доступом, конструктор может быть использован в другом классе для создания нескольких экземпляров... следовательно, он не является строго синглтоном. Если вы объявите синглтон как абстрактный, он вообще не может быть инстанцирован... следовательно, это не синглтон.

10
ответ дан 29 November 2019 в 20:32
поделиться

На самом деле "можно" скомпоновать что угодно, но в данном случае это нецелесообразно. Нет никакой реальной причины использовать паттерн singleton с наследованием, он просто не предназначен для этого.

4
ответ дан 29 November 2019 в 20:32
поделиться

Ниже приведена одна реализация шаблона синглтона, объясненная в GOF о создании синглтона с наследованием. Здесь необходимо изменить родительский класс, чтобы добавить новый производный класс. Переменная среды может использоваться для создания соответствующего конструктора производного класса.

Mainfile – 1
#include <iostream>
#include <string>
#include "Singleton.h"
using namespace std;

int main(){

     Singleton::instant().print();
     cin.get();
}
Singleton.h
#pragma once
#include <iostream>
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(){};

};
2
ответ дан 29 November 2019 в 20:32
поделиться

Частный конструктор виден другим внутренним классам этого синглтонного класса. Так что да, технически класс-синглтон с приватным конструктором может быть расширен своим внутренним классом. Но зачем делать что-то подобное - уму непостижимо.

3
ответ дан 29 November 2019 в 20:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: