Интерфейс Java с параметрами в качестве другого интерфейса

1

У меня есть интерфейс 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

Я согласен с контрактом, который указан интерфейсом фильтра прямо? Но в чем логика, почему это не позволяет мне это делать?

Теги:
interface

3 ответа

10
Лучший ответ

Я согласен с контрактом, который указан интерфейсом фильтра прямо?

Неа.

Интерфейс позволяет абонентам передавать любую реализацию IFilterData.

Ваш класс принимает только одну конкретную реализацию.

  • 0
    Хм ... Понял. Тогда как мы поддерживаем эти варианты использования в Java?
  • 0
    @Apps: какие варианты использования? почему ты хочешь сделать это?
Показать ещё 2 комментария
2

Предполагая, что вы имели в виду

public class SampleFilterImpl implements Filter {

потому что вы могли бы

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

Если flag был true и filter ссылался на объект типа SampleFilterImpl, то вы должны передать аргумент типа SomeOtherFilterData который не будет соответствовать типу параметра SampleFilterData.

  • 0
    Хорошо. Я понял.
2

Нет, вы не соглашаетесь с интерфейсом Filter. Интерфейс Filter указывает, что вы можете передать IFilterData в экземпляр Filter, что означает, что вы сможете это сделать:

public class SomeOtherFilterData implements IFilterData { ... }

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

Однако ваша acceptData позволяет acceptData только SampleFilterData, что нарушает контракт.

Более общий принцип подписи Лискова гласит, что вы можете только ослабить предпосылки и/или укрепить постусловия интерфейса. В Java это означает, что вы можете использовать под-классы для типа возвращаемого значения и типы исключенных исключений переопределенного метода или бросать меньше типов исключений.

Одним из решений было бы сделать ваш Filter общим:

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

и имеют SampleFilterImpl реализуют Filter<SampleFilterData>. В зависимости от вашего IFilterData использования вы можете полностью удалить IFilterData и разрешить Filter для любого T

  • 0
    Является ли использование Generics единственным способом, с помощью которого мы можем разработать такие сценарии?
  • 0
    @Apps Для статически проверяемого кода, я думаю, что это единственное решение.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню