Apps
Apps

Reputation: 3389

Java interface with parameters as another interface

I have a Java interface like

    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?

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

where SampleFilterData implements IFilterData

I'm agreeing to the contract which is specified by the Filter interface right? But what is the logic why it is not allowing me to do this?

Upvotes: 1

Views: 83

Answers (3)

Mattias Buelens
Mattias Buelens

Reputation: 20159

No, you're not agreeing to the Filter interface. The Filter interface specifies that you can give any IFilterData to a Filter instance, meaning that you should be able to do this:

public class SomeOtherFilterData implements IFilterData { ... }

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

However, your acceptData only allows for SampleFilterData to be passed, which violates the contract.

More general, the Liskov substitution principle states that you can only weaken the preconditions and/or strengthen the postconditions of an interface. 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.

One solution would be to make your Filter generic:

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

and have SampleFilterImpl implement Filter<SampleFilterData>. Depending on your use case, you might be able to remove IFilterData completely and allow Filter to be implemented for any T.

Upvotes: 2

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279930

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.

Upvotes: 2

SLaks
SLaks

Reputation: 887365

I'm agreeing to the contract which is specified by the Filter interface right?

Nope.

The interface lets callers pass any implementation of IFilterData.

Your class only accepts one specific implementation.

Upvotes: 10

Related Questions