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

Forcing subclasses to have a particular factory method or constructor

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

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

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

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

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

如果只是为了代码的一致性(这是一件好事!),那么您只需在开发代码库时确保一致性即可。基础 class 中的评论可以在这里发挥很大作用,代码审查和其他 "soft" 技术也可以。

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

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

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

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

您又遇到了与 "how do I ensure that every subclass has a FooMaker implementation?" 相同的问题,我想再说一遍,您不必为此担心。如果您将 FooMaker 设为代码的 "starting point",而不是 subclass,那么 subclass 在做什么并不重要;重要的是您的 FooMaker 为您提供了从字符串到 Foo 的方法,并且每个 Foo 都有返回字符串的方法。

下面的代码确保每个subclass都需要实现静态方法,如果subclass没有实现该方法,那么在构造classes时会失败,尽可能接近编译时错误,但不是在编译时

抛出的异常很清楚,程序一启动就瞬间失败

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) {

   }

}

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

子class 必须看起来像这样

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

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

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

复制 Functional 的对象