У меня есть основной вопрос в Java, но это общий вопрос в ООП. Почему интерфейсы позволяют устанавливать поля? Разве это не противоречит тому, что должен делать интерфейс?
Как я это понял, интерфейс — это то, что на английском языке было бы прилагательным. Итак, если мой класс реализует интерфейсы Runnable и Serializable, я гарантирую пользователю, что мой класс будет удовлетворять условиям Runnable и Seriablizable. Однако это означало бы, что интерфейсы «неактивны», но им разрешено иметь поля в Java.
Я что-то пропустил?
Все поля в интерфейсе public static final , т.е. они являются константами.
Обычно рекомендуется избегать таких интерфейсов, но иногда вы можете найти интерфейс, который не имеет методов и используется только для того, чтобы содержать список постоянных значений.
Прежде всего, существует разница между OOP paradigm и реализацией OOP в Java , поэтому одни и те же слова могут означать разные вещи.
В ООП интерфейс парадигмы — это то, что можно сделать с объектом (или что объект может сделать для вас ). Любой объект может иметь несколько интерфейсов и, следовательно, играть разные роли. Например, кто-то может работать программистом и иметь возможность создавать программы, но в то же время он может быть мужем и отцом и, таким образом, иметь возможность оплачивать счета для своей семьи и заботиться о детях. Здесь «программист», «муж» и «отец» являются интерфейсами, а человек — объектом, который их реализует. Обратите внимание, что интерфейсы не подразумевают наличие каких-либо конкретных функций (полей) для реализации объекта, а просто действия, которые этот объект должен выполнять.
Java более или менее следует этой идее, но поскольку любая реализация парадигмы имеет свои особенности. Java позволяет описывать методы, то есть действия, которые реализующий объект должен выполнять, но не какие-либо детали реализации, поэтому ничего об объектных полях или частных методах.
Но как насчет полей констант ( public final static )? Являются ли они частью реализации или интерфейса. Это может быть и то, и другое. Например. Интерфейс «программист» может иметь постоянный WORK_HOURS установлен на «8». Таким образом, Java позволяет также описывать константы в интерфейсах.
Обратите внимание, что Java только помогает вам создать хороший дизайн ООП, но он не требует этого. В частности, не все общедоступные методы объекта должны существовать и в интерфейсе. Например, методы getter и setter обычно общедоступны, но на самом деле они являются частью реализации , а не интерфейсом, и поэтому не стоит вводить их в интерфейс.
(Пожалуйста, также обратите внимание, что большинство вещей, которые я описал здесь, относятся к основному ООП, как в Java, но есть и другие типы ООП, такие как прототип, в частности, реализованные в JavaScript).
Ключевое слово interface используется для создания полностью абстрактных классов. Создатель интерфейса определяет имена методов, списки аргументов и типы возвращаемых значений, но не тела методов.
Наличие слова interface означает, что именно так должны выглядеть все классы, которые реализуют данный интерфейс. Таким образом, любой код, использующий конкретный интерфейс, знает только то, какие методы вызываются для этого интерфейса, но не более того.
Чтобы создать интерфейс, используйте ключевое слово interface вместо class. Как и в случае с классами, вы можете добавить перед словом interface спецификатор доступа public (но только если интерфейс определен в файле, имеющем то же имя) или оставить для него дружественный доступ, если он будет использоваться только в пределах своего пакета. Интерфейс может содержать поля, но они автоматически являются статическими (static) и неизменными (final). Все методы и переменные неявно объявляются как public.
Класс, который собирается использовать определённый интерфейс, использует ключевое слово implements. Оно указывает, что интерфейс лишь определяет форму, а вам нужно наполнить кодом. Методы, которые реализуют интерфейс, должны быть объявлены как public.
Интерфейсов у класса может быть несколько, тогда они перечисляются за ключевым словом implements и разделяются запятыми.
Интерфейсы могут вкладываться в классы и в другие интерфейсы.
Если класс содержит интерфейс, но не полностью реализует определённые им методы, он должен быть объявлен как abstract.
Интерфейсы — это не классы. С помощью ключевого слова new нельзя создать экземпляр интерфейса:
Но можно объявлять интерфейсные переменные:
При этом интерфейсная переменная должна ссылаться на объект класса, реализующего данный интерфейс.
Рассмотрим быстрый пример создания интерфейса. Выберите в меню File | New | Interface и придумайте имя для нового интерфейса. В полученной заготовке добавьте два имени метода (только имена, без кода).
Создайте или откройте какой-нибудь класс, к которому нужно применить интерфейс, и добавьте к нему implements SimpleInterface. Среда разработки подчеркнёт красной линией имя класса и предложит добавить методы, которые требуются интерфейсом. Соглашаемся и получаем результат:
Среда разработки сгенерировала два метода и использовала в качестве возвращаемых результатов значения по умолчанию. Это могут быть и нулевые значения и null. Осталось подправить шаблоны созданных методов под свои задачи. Например, так:
Первый метод возвращает имя класса, а второй — возраст кота (странно, что всем котам будет по пять лет, но это лишь пример).
Здесь важно понять роль интерфейса. Мы лишь придумываем имена, а класс уже реализует нужную задачу. Для примера можно создать в интерфейсе метод play() для класса Пианино и класса Гитара, так как играть можно на обеих инструментах. Но код в методах будет отличаться, так как принцип игры на инструментах совершенно разный.
Содержание
- Константы в интерфейсах
- Расширение интерфейсов
- Методы обратного вызова
- Слушатели
Константы в интерфейсах
Интерфейсы можно использовать для импорта констант в несколько классов. Вы просто объявляете интерфейс, содержащий переменные с нужными значениями. При реализации интерфейса в классе имена переменных будут помещены в область констант. Поля для констант становятся открытыми и являются статическими и конечными (модификаторы public static final). При этом, если интерфейс не будет содержать никаких методов, то класс не будет ничего реализовывать. Хотя данный подход не рекомендуют использовать.
Расширение интерфейсов
Интерфейс может наследоваться от другого интерфейса через ключевое слово extends.
Методы обратного вызова
Интерфейсы часто используются для создания методов обратного вызова (callback). Рассмотрим такой пример. Создадим новый класс SubClass с интерфейсом MyCallback:
У интерфейса мы определили один метод callBackReturn(). Далее в классе мы создали объект интерфейса и инициализировали его в конструкторе класса. В классе также был создан метод doSomething(), в котором может содержаться какой-то сложный код. В конце метода вызывается метод интерфейса. В данном случае мы сами создали метод и знаем его код. Но во многих случаях, вы будете использовать готовый метод какого-то класса и вы не будете знать, что именно содержится в этом методе. Вам надо только знать, что такой метод существует, например, из документации и он выполняет конкретную задачу.
Переходим в код активности и подключаем интерфейс через ключевое слово implements:
Среда разработки поможет вставить шаблон метода интерфейса.
Теперь мы можем использовать метод обратного вызова callBackReturn() для решения своих задач. Допустим у нас есть текстовая метка и кнопка. При щелчке выполняется какой-то сложный код из класса SubClass. Когда он закончит работу, то сработает метод обратного вызова callBackReturn(), в котором пропишем нужные действия.
Слушатели
Очень часто для интерфейса используют слово Listener, например, у кнопки есть интерфейс OnClickListener.
Мы можем создавать подобные слушатели для собственных классов.
Также интерфейсы часто используются при работе с фрагментами.
Требуется определённая практика и опыт, чтобы быстро разбираться в коде с использованием интерфейсов, так как приходится отслеживать цепочку вызовов из разных классов. Но бояться их не нужно.
Прежде всего я создаю интерфейс, который будет вести логи операции.
public interface Logs < public void Log (); >
После чего я создаю интерфейс, который будет обрабатывать логи.
После чего создаю класс, который будет например, собирать информацию логи.
Теперь, мне нужно получить доступ к булевому значению TurnKey, который находится в классе в MyLogs, интерфейса MyLogs.
Как это сделать?
ПС,
Например, мне не составляет труда получить и изменить доступ таким образом.
Делаю класс с приватными полями.
И собственно главный класс, где эти поля редактируются.
Как сделать тоже самое, но с интерфейсом, который содержит класс?
Источник: