0

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

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

  • toString, 将对象转换为String.
  • fromString,它从 a 中获取一个实例String

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

4

2 回答 2

3

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

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

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

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

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

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

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

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

于 2015-02-10T01:06:26.460 回答
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) {

   }

}

私有接口构造确保只有 lambda 可以用于实现该方法

子类必须看起来像这样

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

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

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

于 2015-02-10T02:10:34.917 回答