所以假设我定义了以下内容:
public interface IExportTool {
void export(IReport iReport);
}
然后尝试使用它:
public class KibanaExporter implements IExportTool{
public void export(IReport kibana) {
kibana = (Kibana) kibana;
((Kibana) kibana).toJSON();
}
}
但是还有其他类也会再次做类似的事情:
public class MetricExporter implements IExportTool{
public void export(IReport metric) {
metric = (Metric) metric;
((Metric) metric).toJSON(); // might be something else here like toXML etc
}
}
请注意,Kibana和Metric都分别实现了IReport<KibanaRow>
和IReport<MetricRow>
,而IReport接口看起来像这样:
public interface IReport<T> {
void addRow(T row);
}
我不喜欢所有这样的转换,感觉不正确,也无法自动完成,所以有什么建议如何正确地做到吗?
答案 0 :(得分:3)
从您发布的内容来看,很明显Kibana
和Metric
都是IReport
的子类型。
在这种情况下,您可以使接口通用:
interface IExportTool<R extends IReport> {
void export(R iReport);
}
然后以这种方式更改实现:
public class KibanaExporter implements IExportTool<Kibana>{
public void export(Kibana kibana) {
kibana.toJSON();
}
}
并且:
public class MetricExporter implements IExportTool<Metric> {
public void export(Metric metric) {
metric.toJSON();
}
}
此版本允许编译器理解并验证只有IReport
子类型的实例才会传递到export()
。使用此代码的代码将由编译器验证,这样MetricExporter().export()
只能与类型为Metric
的对象一起调用,而KibanaExporter().export()
只能与类型为Kibana
的对象一起调用。
这样,就不再需要强制类型转换。