【问题标题】:Java: singleton from base classJava:来自基类的单例
【发布时间】:2014-03-26 23:49:19
【问题描述】:

假设我们有基类:

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 具有类 Base 的功能的最优雅的方式/模式是什么?

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

【问题讨论】:

  • 只需将SingletonBase 的所有构造函数声明为私有
  • 忘了说,我不能修改基类——它来自外部库。
  • 但是 SingletonBase 只能有一个构造函数...只需删除公共的构造函数即可。为什么在地球上你对 Singleton 使用抽象?如果您想重用框架代码,只需使用单例中的 Base 对象即可。
  • 如果你不能直接访问base的源,你可以诉诸反射。
  • 也许你可以“更喜欢组合而不是继承”,我的意思是在你的 Singleton 类中保留一个 Base 的实例。您应该记住,通过继承,应该能够使用每个子类而不是超类,并且制作单例子类并不完全适合。也许想想你是否真的需要一个单身人士。

标签: java design-patterns singleton


【解决方案1】:

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

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;
    }
    /* ... */
}

【讨论】:

  • 是的,我不知道为什么我认为构造函数是继承的。谢谢!
  • 我投了反对票,因为如果你删除(或者更好的词:省略)子类中的构造函数,仍然会调用超类构造函数。
  • @ScottShipp 我想你没有在这里得到问题的上下文。
  • 在这种情况下,将类作为抽象类是一个好主意。谢谢!
【解决方案2】:

您可以使SingletonBase 只是一个普通的子类,并将单例部分委托给不同的类。 我不知道你的具体上下文是什么,但你会拥有Subclass extends Base,在其他地方你会拥有SingletonContainer 或类似的东西,你拥有public static Subclass getInstance() 的方法。

这样,您将拥有通常的继承以及单例效应,因为SingletonContainer 将负责只保留一个子类实例。

【讨论】:

    【解决方案3】:

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

    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;
      }
      /* ... */       
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多