Что делать с неиспользуемыми методами @Override?

Как известно, при реализации интерфейсов некоторые методы необходимо перезаписывать. В моем случае довольно часто приходится перезаписывать методы, которые мне не нужны. В результате мои классы забиты пустыми методами @Override.

Пример:

@Override
public void keyPressed(KeyEvent ke) {
    // TODO Auto-generated method stub
    if (ke.getKeyCode() == KeyEvent.VK_END) {
        System.exit(0);
    }
}

@Override
public void keyReleased(KeyEvent arg0) {}

@Override
public void keyTyped(KeyEvent arg0) {}

В этом примере я хотел бы закрыть свою программу, нажав клавишу «End» на клавиатуре. Как только я реализую требуемый интерфейс «KeyListener», я должен перезаписать методы «keyReleased» и «keyTyped». Однако, поскольку мне не нужны эти два метода, они остаются пустыми в моем классе.

Пример примечания:

Конечно, эти 3 строчки кода не представляют большой проблемы. Реализация интерфейса MouseListener выглядела бы совершенно иначе, где пришлось бы перезаписывать почти вдвое большее число. Не говоря уже о том, как это будет выглядеть при реализации нескольких интерфейсов.

Проблема:

  1. Из-за пустых методов весь код производит нечистое впечатление.
  2. Любая путаница при передаче кода третьим лицам.
  3. Во многих местах рекомендуется удалять неиспользуемый код. В моем случае эти пустые методы @Override не использовались бы. (например, здесь)

Как лучше всего очистить эти пустые методы @Override и сделать мой код более «чистым»?

Редактировать

Не запутайтесь на моем примере. Сам вопрос был о неиспользуемых методах переопределения в целом, а не о проблеме в моем примере. Извините, если я не понял

Вместо этого использовать KeyAdapter? тогда вам нужно только переопределить методы, которые вы хотите

khelwood 23.08.2018 15:19

Создайте абстрактный класс с «пустыми» реализациями. Для ваших конкретных классов расширьте этот абстрактный класс и переопределите только те методы, которые вам нужны.

k5_ 23.08.2018 15:20

Imho, лучшее, что вы можете сделать, это попытаться найти интерфейс, который не объявляет поведение, которое вам не нужно, потому что мы видим здесь нарушение принципа сегрегации интерфейса: en.wikipedia.org/wiki/Interface_segregation_principle

nyarian 23.08.2018 15:21

@ Джеспер Совершенно верно. Спасибо.

khelwood 23.08.2018 15:22

Возможный дубликат Зачем мне нужны keyPressed (), KeyRelesed и keyTyped () в KeyListener? - Джава

user1803551 23.08.2018 15:25

Так что KeyAdapter подойдет для моего примера. Но в целом для обработки неиспользуемых методов переопределения способ, предложенный k5_, был бы хорошим решением. Я правильно понял?

GreenAtomic 23.08.2018 15:26

@ user1803551 не думаю, что это дубликат. Вы просто ссылаетесь на мой пример. Сам вопрос касался вообще неиспользуемых методов переопределения. Извините, если я не понял

GreenAtomic 23.08.2018 15:27
KeyAdapter использует способ, описанный k5_. Также проблема дизайна может заключаться в том, что вы добавили слишком много вещей в интерфейс, когда вы используете только его части. Тогда вы сможете провести рефакторинг для нескольких интерфейсов и выбрать подходящий.
Kayaman 23.08.2018 15:33

Обновите версию java до 8 и установите методы интерфейса по умолчанию.

DEVENDRA 23.08.2018 15:35

@Devendra, это довольно уродливо с точки зрения дизайна.

Kayaman 23.08.2018 15:36

См. Также Как реализовать только часть интерфейса.

user1803551 23.08.2018 15:39

И после того, как вы отредактировали вопрос, новый целевой дубликат - избегать реализации метода, который есть в интерфейсе - java

user1803551 23.08.2018 15:43

@kayaman Я согласен, что дизайн абстрактного класса - лучший подход, когда вы пишете код с самого начала, но если вы работаете с устаревшим кодом, вам нужно найти обходные пути.

DEVENDRA 23.08.2018 15:46
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
13
1 137
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Учитывая ваш интерфейс:

interface FooBarBaz {
    void foo();
    int bar();
    String baz();
}

Вы создаете абстрактный класс, реализующий этот интерфейс и предоставляющий реализации по умолчанию для всех методов:

abstract class AbstractFooBarBaz implements FooBarBaz {
     @Override
     public void foo() {
         // NOP by default
     }

     @Override
     public int bar() {
         return 0; // 0 by default
     }

     @Override
     public String baz() {
         return null; // null by default
     }
 }

И затем вы можете использовать его в своем коде следующим образом и переопределить только те методы, которые вам нужны:

FooBarBaz fooBarBaz = new AbstractFooBarBaz() {
    @Override
    public int bar() {
        return 9000;
    }
};

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

Другие вопросы по теме