Реализовать интерфейс и переопределить методы в Java?

#java #interface #implements

#java #интерфейс #реализует

Вопрос:

Почему вы должны переопределять все методы интерфейса?

Например, если у меня есть

 public class Foo extend JFrame implements ActionListener, KeyListener {
      foo(){
      }
    @Override
    public void keyPressed(KeyEvent arg) {          
    }

    @Override
    public void keyReleased(KeyEvent arg) {
}

    @Override
    public void keyTyped(KeyEvent arg) {        
    }
}
  

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

Я также не хочу использовать abstract, поскольку это означает, что я не могу создать экземпляр объекта (по крайней мере, так говорит мой компилятор)

Ответ №1:

Конкретные классы всегда должны реализовывать все методы интерфейса. Если вы еще не расширяли, JFrame вы могли бы расширить KeyAdapter . Он реализует пустые методы для KeyListener , чтобы избежать их записи. Вы могли бы использовать анонимный класс с этим внутри вашего Foo класса, например:

 addKeyListener(new KeyAdapter() {
    public void keyTyped(KeyEvent e) {
        // handle typed key here
    }
});
  

Комментарии:

1. Я могу расширить только один класс, хотя?

2. Да, вы можете расширить только один класс. Вам пришлось бы разделить вашу ключевую логику на отдельный класс, который расширяется KeyAdapter . Тогда вам нужно будет написать только один метод, который вы хотите переопределить.

Ответ №2:

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

Ответ №3:

Вы можете создать родительский класс Foo, который имеет эти пустые методы, и заставить Foo реализовывать только те методы, которые вы хотите видеть.

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

Ответ №4:

Это именно то, для чего KeyAdapter предназначен класс: он реализует все методы интерфейса (но ни одна из реализаций ничего не делает). Поскольку вы не можете расширить два класса, вам следует использовать внутренний класс для вашего слушателя (что в любом случае является более чистым дизайном):

 public class Foo extend JFrame {
      foo(){
          ...
          component.addKeyListener(new MyKeyListener());
          ...
      }

    private class MyKeyListener extends KeyAdapter{
        @Override
        public void keyPressed(KeyEvent arg) {          
        }
    }
}
  

Комментарии:

1. Хотел бы я дать два правильных ответа. В качестве вопроса, как я могу добавить это в сам JFrame, потому что добавление его в getContentPane() не работает — Обратите внимание, что это работает с JTextField, хотя

2. @user551841: KeyListeners работают только с компонентами, которые фактически получают фокус клавиатуры. Для глобального прослушивания ключевых событий вам, вероятно, нужно работать с KeyEventDispatcher или, если вас интересуют только конкретные клавиши (например, горячие клавиши), используйте привязку ключа. Подробнее читайте в руководствах: download.oracle.com/javase/tutorial/uiswing/misc /…

Ответ №5:

Если вы реализуете интерфейс, это означает, что реализованный объект может быть использован в любом сценарии, где ожидается реализация. С этой точки зрения совершенно очевидно, что вы должны реализовать все методы интерфейса, иначе вы не можете на самом деле сказать, что вы его реализовали. например, если у меня есть ICalculator интерфейс с методом Add and Subtract , а вы хотите только реализовать Add , может ли результирующий класс действительно использоваться другим проектом, которому нужен ICalculator?

Однако я вполне понимаю ваш гнев по поводу реализации некоторых интерфейсов во фреймворках сегодня, поскольку они явно нарушают принцип разделения интерфейсов. Это означает, что некоторые интерфейсы представляют собой сгустки нескольких функциональных возможностей, которые можно использовать вместе, чтобы сделать что-то полезное. Например. если ICalculator использует, вместо просто базовых Add , Divide и т.д. методов, я начал добавлять такие методы, как StandardDeviation которые не являются существенными для природы Calculator объекта.

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

Ответ №6:

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