我 70% 确信这是不可能的,但是有没有办法确保子类具有特定的构造函数或工厂方法?
在这种情况下,我正在尝试创建一个StringSerializable
需要子类具有以下方法的方法
toString
, 将对象转换为String
.fromString
,它从 a 中获取一个实例String
。
显然,在第一种情况下,我可以toString
抽象一下。另一方面,有一个非静态的fromString
似乎是有问题的。但是,我无法创建抽象静态方法。我也不认为构造函数是完全合适的。
我 70% 确信这是不可能的,但是有没有办法确保子类具有特定的构造函数或工厂方法?
在这种情况下,我正在尝试创建一个StringSerializable
需要子类具有以下方法的方法
toString
, 将对象转换为String
.fromString
,它从 a 中获取一个实例String
。显然,在第一种情况下,我可以toString
抽象一下。另一方面,有一个非静态的fromString
似乎是有问题的。但是,我无法创建抽象静态方法。我也不认为构造函数是完全合适的。
你是对的;在编译时强制它是不可能的。您可以在运行时执行各种技巧(例如在测试中使用反射),仅此而已。
但问问你自己:你为什么要这样要求?您不能动态调用静态方法或构造函数(通过反射除外),那么如果您拥有这些所需的工厂,您将如何使用它们呢?
如果只是为了代码的一致性(这是一件好事!),那么您只需要在开发代码库时确保一致性。基类中的注释在这里可以大有帮助,代码审查和其他“软”技术也可以。
如果您计划在反射中使用工厂,则可以在测试中使用类似的反射,以确保每个子类都有它需要的位。
另一种选择是创建一个非静态工厂:
public interface FooMaker() {
Foo create(String arg);
}
...并使用它,而不是静态fromString
方法。
你又遇到了同样的问题:“我如何确保每个子类都有一个FooMaker
实现?” 我再说一遍,你不应该担心这个。如果您将FooMaker
代码作为“起点”而不是子类,那么子类在做什么并不重要;重要的是您FooMaker
的 s 为您提供了从字符串到Foo
s 的方法,并且每个Foo
都有返回到字符串的方法。
以下代码确实确保每个子类都需要实现静态方法,如果子类没有实现该方法,它将在构造类时失败,尽可能接近编译时错误,但不是在编译时
抛出的异常非常清楚,程序启动时会立即失败
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 的对象