Один и тот же метод в суперклассе и интерфейсе - PullRequest
2 голосов
/ 22 сентября 2011

Я расширяю класс, а также реализую интерфейс, оба содержат метод с именем doFilter, это последний метод в моем суперклассе и, разумеется, абстрактный метод из моего интерфейса. Итак, теперь я получаю сообщение об ошибке компилятора.

Как мне решить эту проблему.

Мой класс фильтра:

public class MyCacheFilter extends CachingFilter implements Filter {
    // here is error, as compiler is thinking I am overriding dofilter of
    // CacheFilter, although I have not specified any @Override annotation

    public doFilter() {
    }
}

Ответы [ 5 ]

3 голосов
/ 22 сентября 2011

Если метод предоставляется CachingFilter, вам не нужно указывать реализацию в MyCacheFilter.(На самом деле, как вы обнаружили, вы не можете .)

Если вы действительно хотите, чтобы поведение doFilter отличалось от того, которое обеспечивает CachingFilter, тогда наследованиене вариант.В этом случае рассмотрите возможность использования композиции:

public class MyCacheFilter implements Filter {

    CachingFilter cachingFilter = ...

    @Override
    public void doFilter() {
        ...
        possibly refer to cachingFilter...
        ...
    }

    public String otherMethod() {
        // delegate to cachingFilter
        return cachingFilter.otherMethod();
    }
}

[...], хотя я не указал аннотацию @Override

Независимо от того, указали ли вы явно @Override, не имеет значения.

1 голос
/ 22 сентября 2011

Проблема в том, что метод объявлен final в суперклассе. Это означает, буквально, «этот метод не может быть переопределен». Если вам нужно поместить свою собственную логику в doFilter(), вы не можете расширить CachingFilter.

В Java нет понятия , где вы переопределяете метод. Интерфейс - это контракт, который сообщает другим, что может сделать ваш класс. Полный контракт - это сумма всех реализованных интерфейсов. Неважно, присутствует ли идентичная сигнатура метода в нескольких интерфейсах. Класс выполнения контракта.

Наследование начинается сверху (т. Е. Object), и каждый переопределенный метод заменяет любые ранее существующие определения любого родителя в качестве общедоступного метода - , за исключением , если метод объявлен final. Это говорит компилятору, что реализация этого метода не может быть переопределена, это окончательная его версия.

РЕДАКТИРОВАТЬ: Я не знаю, из чего исходит CachingFilter, который вы используете, но общий шаблон в средах, наложенных поверх других платформ или стандартного API Java, заключается в создании окончательной реализации метода, требуемого API (doFilter() в этом случае), но добавьте еще один "внутренний" метод (например, internalDoFilter()), который вызывается из doFilter(). Расширяющиеся классы могут затем безопасно переопределить «внутренний» метод, при этом гарантируя, что любая существенная логика в doFilter() по-прежнему выполняется правильно.

0 голосов
/ 07 октября 2011

Попробуйте реализовать интерфейс как анонимный.

public class MyClass extends MySuperClass implements MyInterface{

MyInterface myInterface = new MyInterface(){

/* Overrided method from interface */
@override
public void method1(){

}

};

/* Overrided method from superclass*/
@override
public void method1(){

}

}
0 голосов
/ 22 сентября 2011

Если доступен CachingFilter.dofilter (), это будет метод в вашем дочернем классе.Так что вам не нужно переопределять это.Если вы хотите переопределить, метод не должен быть окончательным.

0 голосов
/ 22 сентября 2011

К сожалению, нет способа разрешить такие конфликты напрямую, кроме как переосмыслить дизайн своего класса. Вы могли бы

  • переименуйте метод в интерфейсе или
  • изменить MyCacheFilter на содержать a CachingFilter, а не наследовать от него, или
  • если реализация суперкласса удовлетворяет вашим потребностям, вы можете (как упоминалось @aioobe) вообще исключить метод из вашего подкласса.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...