开发者

Is it possible to apply inheritance to a Singleton class?

开发者 https://www.devze.com 2022-12-29 00:37 出处:网络
Today I faced one question in interview. Is it possible to apply inheritance concept on Singleton Classes? I said since the constru开发者_如何转开发ctor is private, we cannot extend that Singleton cla

Today I faced one question in interview. Is it possible to apply inheritance concept on Singleton Classes? I said since the constru开发者_如何转开发ctor is private, we cannot extend that Singleton class.

Next thing he asked me is to apply inheritance on that Singleton class. So, I made the Singleton's constructor as protected thinking that child's constructor also has be protected. But I was wrong the child can have a modifier either equal to or higher than that.

So, I asked him to give a real world example on such a case. He was not able to give me one and said that I cant ask questions and wanted me to tell whether this scenario is possible or not.

I went kind of blank. My question here is,

  • Is this possible?
  • Even if it is possible, what is the use of it?
  • What real world scenario would demand such a use?


Citing the bible:

Use the Singleton pattern when [...] the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code.

The Singleton pattern has several benefits: [...] 3. Permits refinement of operations and representation. The Singleton class may be subclassed, and it's easy to configure an application with an instance of this extended class. You can configure the application with an instance of the class you need at run-time.

As for how to implement this: the book suggests several way, the most sophisticated of which is a registry in which instances are looked up by name.


Yes, it is technically possible, as singleton is a design pattern and not a language construct that could have inheritance restrictions. I would just reimplement the public [Object] getInstance() method in the child classes (see below).

And, yes, singletons can also benefit from inheritance as they may share similar but not identifical behaviours with other singletons.

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;
    }       
}

EDIT: as Eyal pointed out in his comments below, the constructor in the super class had to be made protected (instead of private), otherwise it would not be visible to the child classes and the code would not even compile.


You can create an abstract base class with a bunch of common attributes and methods, and then create a number of subclasses as singleton classes. That is "applying the inheritance concept" ... in a useful way.

But what you cannot do is create a subclass of a strictly implemented singleton class. If you declare the singleton classes constructor as private a subclass won't compile. If you declare it with some other access, the constructor could be used in another class to create multiple instances ... ergo it is not strictly a singleton. If you declare the singleton as abstract, it cannot be instantiated at all ... ergo it is not a singleton.


Its 'possible' to hack anything together really, but in this case it is not really advisable. There's no real reason to use the singleton pattern with inheritance, its just not meant for it.


A private constructor is visible to other inner classes of that singleton class. So yes, technically a singleton class with a private constructor can be extended by its inner class. But why would you do something like that is beyond me.


Below is one implementation of singleton pattern explained in GOF about creating singleton with inheritance. Here the parent class should be modified to add a new derived class. Environment variable can be used to instantiate appropriate derived class constructor.

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(){};

};


I'm guessing this isn't what he wasn't looking for, but if you want to get technical you could also mention that Singleton is a pattern, not an implementation. Messing with the class constructor isn't the only way to have a Singleton, you could have a factory enforcing the pattern, in which case you can use inheritance in exactly the same way as with other classes.


You could make the constructor package-private. This way, no classes outside the package could instantiate the Singleton class but derived classes could call the upper class constructor.

But, as others said, this is really not advisable.

Stupid interview question by the way.

0

精彩评论

暂无评论...
验证码 换一张
取 消