Java接口以参数作为另一个接口

时间:2014-12-23 14:21:02

标签: java interface

我有一个像

这样的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接口指定的合同吗?但是为什么它不允许我这样做的原因是什么呢?

3 个答案:

答案 0 :(得分:10)

  

我同意Filter接口指定的合同吗?

不。

该界面允许调用者传递 IFilterData的任何实现。

您的班级只接受一个特定的实施。

答案 1 :(得分:2)

假设你的意思

public class SampleFilterImpl implements Filter {

因为你可以

Filter filter = (flag) ? new SampleFilterImpl() : new SomeOtherFilterImpl();
filter.acceptData(new SomeOtherFilterData()); // not SampleFilterData

如果flagtruefilter引用了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