如何继承单身人士

时间:2015-01-07 16:22:33

标签: java design-patterns singleton

有时需要继承单例,但因为在单例中你使用的是静态引用和无法覆盖的静态方法。

例如(Java):

public class Singleton {
    private static Singleton instance = null;

    public static Singleton getInstance() {
        if (instance == null)
            instance = new Singleton();
        return instance;
    }
}

如果我使用“SingletonChild”类继承“Singleton”,我将无法通过调用getInstance()方法生成实例。如果我将创建另一个getInstanceChild()方法,那么基本方法:getInstance()也将被公开。

2 个答案:

答案 0 :(得分:1)

您可以使用适配器模式并将单例包装为另一个对象。如果您还有Singleton和Adapter共享一个接口,那么调用代码不必知道传递哪个接口。

interface MyInterface{
    String foo();

    void bar();
}

public class Singleton implements MyInterface{
  //..same as before

}


public class Adapter implements MyInterface{
     private MyInterface delegate;

     public Adapter(MyInterface adaptMe){
        //check for null in real code
        this.delegate = adaptMe;
     }

     //delegate to bar
     public void bar(){
         delegate.bar();
     }

     //override foo
     public String foo(){
        return "AdaptedFoo";
     }
}

然后你的代码可以包装Singleton

MyInterface myInterface = new Adapter(Singleton.getInstance());

答案 1 :(得分:0)

一种方法是使用一个独立的工厂,它将成为这样的类的创造者并确保它们确实是单身。但是这个解决方案存在一个不同的问题,工厂必须知道使用base' Singleton'或者必须延长这个工厂以获得这些知识。

有一种不同的方法可以解决这个问题,让你在不修改工厂的情况下继承新实现的单例。

public abstract class SingletonInheritance {
    public static abstract class AbstractSingleton {
        private static AbstractSingleton instance = null;

        protected AbstractSingleton() {
        }

        public static <T extends Class<? extends AbstractSingleton>>
        AbstractSingleton getInstance(T _class) {
            if (instance == null) {
                try {
                    instance = _class.getDeclaredConstructor().newInstance();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
            }
            return instance;
        }
    }

    public static class Singleton extends AbstractSingleton {
        public String foo() {
            return "Singleton";
        }
    }

    public static class SingletonChild extends Singleton {
        @Override
        public String foo() {
            return "SingletonChild";
        }
    }

    public static void main(String[] args) {
        SingletonChild singletonChild = 
            (SingletonChild) SingletonChild.getInstance(SingletonChild.class);
        System.out.println(singletonChild.foo());
    }
}
  

输出:&#34; SingletonChild&#34;