Java:来自基类的单例

时间:2014-03-26 15:17:15

标签: java design-patterns singleton

让我们假设我们有基类:

public class Base {
      public Base(int i) {
      /* ... */
      }
      /* ... */
}

我们想基于这个类创建单例。问题是类有公共构造函数,因此扩展它将导致单例具有公共构造函数:

public class SingletonBase extends Base {
   private static final SingletonBase _instance = new SingletonBase();

   private SingletonBase() {
      super(0);
   }

  public SingletonBase(int i) {  // Want to avoid this!
     super(i) 
  }

  public static void getInstance() {
     return _instance;
  }
  /* ... */       
}

Singleton当然不能拥有公共构造函数,所以我们要避免这种情况。 那么,什么是最优雅的方式/模式,以适当的Singleton与类Base的功能?

编辑:禁止修改基类,因为它来自外部库。

3 个答案:

答案 0 :(得分:4)

构造函数不是继承的。所以只是 删除这部分,你就会得到你需要的东西。

public SingletonBase(int i) {  // Want to avoid this!
    super(i) 
}

此外,您可能想要Base班级 抽象,以便没有人可以错误地实例化它 通过直接调用Base构造函数。

public abstract class Base {
    public Base(int i) {
        /* ... */
    }
    /* ... */
}

public class SingletonBase extends Base {
    private static final SingletonBase _instance = new SingletonBase();

    private SingletonBase() {
        super(0);
    }

    public static SingletonBase getInstance() {
        return _instance;
    }
    /* ... */
}

答案 1 :(得分:0)

您可以使SingletonBase只是一个普通的子类,并将Singleton-part委托给另一个类。 我不知道你的具体情况是什么,但你会Subclass extends Base和其他地方有SingletonContainer或类似的地方public static Subclass getInstance()

这样,你就可以获得通常的继承以及Singleton效果,因为SingletonContainer只负责保留一个Subclass实例。

答案 2 :(得分:0)

这不是因为你从具有公共构造函数的类继承而必须创建相同的公共构造函数,你可以这样做:

public class SingletonBase extends Base {
   private static final SingletonBase _instance = new SingletonBase();

   private SingletonBase() {
      super(0);
   }

  public static void getInstance() {
     return _instance;
  }
  /* ... */       
}

甚至:

public class SingletonBase extends Base {
   private static final SingletonBase _instance = new SingletonBase();

   private SingletonBase() {
      super(0);
   }

  private SingletonBase(int i) {  // Want to avoid this!
     super(i) 
  }

  public static void getInstance() {
     return _instance;
  }
  /* ... */       
}