简体   繁体   English

具有参数的Java接口作为另一个接口

[英]Java interface with parameters as another interface

I have a Java interface like 我有一个类似的Java接口

    public interface Filter{
        public boolean acceptData(IFilterData data);
    }

    public interface IFilterData{

    }

Why Java is not allowing me to have an implementation class like the below? 为什么Java不允许我拥有如下的实现类?

public class SampleFilterImpl{
    public boolean acceptData(SampleFilterData data){ 
        return true;
    }
}

where SampleFilterData implements IFilterData 其中SampleFilterData implements IFilterData

I'm agreeing to the contract which is specified by the Filter interface right? 我同意Filter接口指定的合同,对吗? But what is the logic why it is not allowing me to do this? 但是为什么不允许我这样做的逻辑是什么?

I'm agreeing to the contract which is specified by the Filter interface right? 我同意Filter接口指定的合同,对吗?

Nope. 不。

The interface lets callers pass any implementation of IFilterData . 该接口允许调用者传递IFilterData 任何实现。

Your class only accepts one specific implementation. 您的课程仅接受一种特定的实现。

Assuming you meant 假设你的意思

public class SampleFilterImpl implements Filter {

because you could have 因为你可能有

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

If flag was true and filter referenced an object of type SampleFilterImpl , then you'd be passing an argument of type SomeOtherFilterData which wouldn't match the parameter type of SampleFilterData . 如果flagtrue并且filter引用了SampleFilterImpl类型的对象,那么您将传递SomeOtherFilterData类型的参数,该参数与SampleFilterData的参数类型不匹配。

No, you're not agreeing to the Filter interface. 不,您同意“ Filter界面。 The Filter interface specifies that you can give any IFilterData to a Filter instance, meaning that you should be able to do this: Filter接口指定您可以将任何 IFilterData赋予Filter实例,这意味着您应该能够执行以下操作:

public class SomeOtherFilterData implements IFilterData { ... }

new SampleFilterDataImpl().acceptData(new SomeOtherFilterData());

However, your acceptData only allows for SampleFilterData to be passed, which violates the contract. 但是,您的acceptData仅允许传递SampleFilterData ,这违反了合同。

More general, the Liskov substitution principle states that you can only weaken the preconditions and/or strengthen the postconditions of an interface. 更一般而言, Liskov替换原则指出,您只能削弱接口的前提条件和/或加强接口的后置条件。 In Java, this means that you can use sub classes for the return type and the thrown exception types of the overridden method, or throw less exception types. 在Java中,这意味着您可以将子类用于重写方法的返回类型和引发的异常类型,也可以使用较少的异常类型。

One solution would be to make your Filter generic: 一种解决方案是使您的Filter通用:

public interface Filter<T extends IFilterData> {
    public boolean acceptData(T data);
}

and have SampleFilterImpl implement Filter<SampleFilterData> . 并让SampleFilterImpl实现Filter<SampleFilterData> Depending on your use case, you might be able to remove IFilterData completely and allow Filter to be implemented for any T . 根据您的用例,您可能可以完全删除IFilterData并允许对任何T实施Filter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM