Reputation: 3389
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
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
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
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