如果你想让你的接口在返回类型中通用,我建议对 JoeC 的评论进行扩展。
从 Java 8 开始,有java.util.function-package,为基本转换提供接口。特别是,接口Function 可用于满足您的目的。我会建议这样的实现:
// file: Parser.java
import java.util.function.Function;
public abstract class Parser<R> implements Function<String, R> {
@Override
public final R apply(String document) {
return (this.parse(document));
}
abstract public R parse(String document);
}
上述示例的实例化如下所示:
String document = ...;
Parser<Map<K, V>> mapParser = ...; // instantiate a fitting Parser
Map<K, V> result = mapParser.parse(document);
(鉴于K 和V 是此代码块中已知的通用参数)。
您可以进一步指定接口以获得更简单的语法:
// file: MapParser.java
import java.util.Map;
public abstract class MapParser<K, V> extends Parser<Map<K, V>> {}
有了这个(空)接口,你可以将上面的代码重写为:
String document = ...;
MapParser<K, V> mapParser = ...; // instantiate a fitting MapParser
Map<K, V> result = mapParser.parse(document);
正如@matoni 所说,可以编写interfacesIParser 和IMapParser 并在它们之上设置抽象类Parser 和MapParser:
// file: IParser.java:
import java.util.function.Function;
public interface IParser<R> extends Function<String,R> {
@Override
default public R apply(String document) {
return (this.parse(document));
}
public R parse(String document);
}
// file: IMapParser.java:
import java.util.Map;
public interface IMapParser<K, V> extends IParser<Map<K, V>> {}
// file: Parser.java:
public abstract class Parser<R> implements IParser<R> {
@Override
public final R apply(String document) {
return (this.parse(document));
}
}
// file: MapParser.java:
import java.util.Map;
public abstract class MapParser<K, V> extends Parser<Map<K, V>>
implements IMapParser<K, V> {}
接口为用户提供了更大的灵活性,因为一个class 可以实现多个interfaces,但只能实现extends 另一个class。然而,不利的一面是,接口IParser 和IMapParser 的开发人员无法强制方法apply(...) 不能被覆盖。因此,理论上,Parser 的实现者可以以不同的方式实现apply(...) 和parse(...),这可能导致意外行为。当使用抽象类 Parser 和 MapParser 时,开发人员会强制 apply(...) 调用 parse(...) 并因此保持一致的行为。