我有一个像
这样的Java界面 public interface Filter{
public boolean acceptData(IFilterData data);
}
public interface IFilterData{
}
为什么Java不允许我有类似下面的实现类?
public class SampleFilterImpl{
public boolean acceptData(SampleFilterData data){
return true;
}
}
其中SampleFilterData
implements
IFilterData
我同意Filter接口指定的合同吗?但是为什么它不允许我这样做的原因是什么呢?
答案 0 :(得分:10)
我同意Filter接口指定的合同吗?
不。
该界面允许调用者传递 IFilterData
的任何实现。
您的班级只接受一个特定的实施。
答案 1 :(得分:2)
假设你的意思
public class SampleFilterImpl implements Filter {
因为你可以
Filter filter = (flag) ? new SampleFilterImpl() : new SomeOtherFilterImpl();
filter.acceptData(new SomeOtherFilterData()); // not SampleFilterData
如果flag
为true
且filter
引用了SampleFilterImpl
类型的对象,那么您将传递SomeOtherFilterData
类型的参数t匹配SampleFilterData
的参数类型。
答案 2 :(得分:2)
不,您不同意Filter
界面。 Filter
接口指定您可以将任何 IFilterData
提供给Filter
实例,这意味着您应该能够执行此操作:
public class SomeOtherFilterData implements IFilterData { ... }
new SampleFilterDataImpl().acceptData(new SomeOtherFilterData());
但是,您的acceptData
仅允许传递SampleFilterData
,这违反了合同。
更一般地说,Liskov substitution principle表明你只能削弱前提条件和/或加强接口的后置条件。在Java中,这意味着您可以将子类用于返回类型和重写方法的抛出异常类型,或者抛出较少的异常类型。
一种解决方案是让您的Filter
通用:
public interface Filter<T extends IFilterData> {
public boolean acceptData(T data);
}
并SampleFilterImpl
实施Filter<SampleFilterData>
。根据您的使用情况,您可以完全删除IFilterData
,并允许Filter
实施T
。