强制子类具有特定的工厂方法或构造函数

时间:2015-02-10 00:58:07

标签: java oop inheritance constructor factory-method

我70%确信这是不可能的,但有没有办法确保子类具有特定的构造函数或工厂方法?

在这种情况下,我试图创建一个StringSerializable,要求子类具有以下方法

  • toString,将对象转换为String
  • fromString,它从String获取实例。

显然,在第一种情况下,我可以将toString抽象化。另一方面,拥有非静态fromString似乎有问题。但是,我无法创建抽象的静态方法。我也不认为构造函数是完全合适的。

2 个答案:

答案 0 :(得分:3)

你是对的;在编译时强制它是不可能的。您可以在运行时执行各种技巧(例如在测试中使用反射),但这就是它。

但问问自己:为什么你想要那个?你不能动态地调用静态方法或构造函数(通过反射除外),那么如果你拥有它们,你将如何使用这些必需的工厂呢?

如果只是为了代码的一致性(这是一件好事!),那么在开发代码库时,您只需要确保一致性。基类中的注释可以在这里发挥很大作用,代码评论和其他“软”技术也可以。

如果计划在反射中使用工厂,那么可以在测试中使用类似的反射来确保每个子类都有它所需的位。

另一个选择是创建一个非静态工厂:

public interface FooMaker() {
    Foo create(String arg);
}

...并使用它,而不是静态fromString方法。

你又遇到了同样的问题:“如何确保每个子类都有FooMaker实现?”我会说你不应该担心这一点。如果将FooMaker作为代码的“起点”,而不是子类,那么子类正在做什么并不重要;重要的是,您的FooMaker会为您提供一种从字符串转到Foo的方式,并且每个Foo都可以返回字符串。

答案 1 :(得分:0)

以下代码确保每个子类都需要实现静态方法,如果子类没有实现该方法,它将在构造类时失败,尽可能接近编译时错误,但不能编译时间

抛出的异常非常清楚,程序启动时会立即失败

public abstract class Base {
   static Functional test;

   static {
      if(test == null) {
        throw new RuntimeException("You need to provide an implementation for the implemntMe method in class base");
      }
   }

   private interface Functional {
      Base implementMe(int whatever, boolean anotherParameter);
   }

   public static void main(final String[] args) {

   }

}

私有接口构造确保只能使用lambdas来实现方法

子类必须看起来像这样

public SubClass extends Base {
   static {
      test = (int whatever, boolean anotherParameter) -> {
         Subclass tmp = new Subclass();
         //construct object
         tmp.setWhatever(whatever);
         return tmp;
      }
   }
}

lamdas就像实现功能接口的内联方法,只有一个抽象方法的接口

您还可以在任何其他地方公开声明该接口,并使用匿名内部类实现它, 但是我的方法确保程序员必须复制并粘贴代码才能重用它, 或者需要从另一个类

复制Functional的对象