Автор: Widowmaker1984

Вопросы 59, 60, 61, 79 (интерфейсы)

"Дайте определение понятию «интерфейс»."
"Какие модификаторы по умолчанию имеют поля и методы интерфейсов?"
"Почему нельзя объявить метод интерфейса с модификатором final или static?"
"Чем отличается абстрактный класс о интерфейса, в каких случаях что вы будете использовать?"


1. Механизм наследования очень удобен, но имеет свои ограничения. В частности мы можем наследовать только от одного класса, в отличие, например, от языка С++, где имеется множественное наследование.

2. В языке Java подобную проблему частично позволяют решить интерфейсы. Они определяют некоторый функционал, не имеющий конкретной реализации, который затем реализуют классы, применяющие эти интерфейсы. При этом один класс может применить множество интерфейсов. Создатель интерфейса определяет имена методов, списки аргументов и типы возвращаемых значений, но не тела методов (в этом смысле можно сказать, что интерфейс — это аналог полностью абстрактного класса).

2.1 Чтобы определить интерфейс, вместо class используется ключевое слово interface.

interface Printable{
void print();
}

скрытый текст2.2. Как и в случае с классами, можно добавить перед словом interface спецификатор доступа public (но только если интерфейс определен в файле, имеющем то же имя) или оставить для него доступ по умолчанию, если интерфейс будет использоваться только в пределах своего пакета. Интерфейс может содержать поля, но они автоматически являются статическими (static) и неизменными (final). Все методы и переменные неявно объявляются как public.

2.2.1. Поскольку такие константы по умолчанию они имеют модификатор доступа public static final, их значение доступно из любого места программы.

2.3. Интерфейсы могут вкладываться в классы и в другие интерфейсы. При применении такого интерфейса нам надо указывать его полное имя вместе с именем класса/интерфейса, в который он вложен.

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

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

3.1. Методы, которые реализуют интерфейс, должны быть объявлены как public. Если класс содержит интерфейс, но не полностью реализует определённые им методы, он должен быть объявлен как abstract.

3.2. Если класс использует несколько интерфейсов, они перечисляются за ключевым словом implements и разделяются запятыми.

4. Интерфейсы — это не классы. С помощью ключевого слова new нельзя создать экземпляр интерфейса.

4.1. Но можно объявлять интерфейсные переменные. При этом интерфейсная переменная должна ссылаться на объект класса, реализующего данный интерфейс. Например, если класс Journal реализует интерфейс Printable, то переменная типа Printable может хранить ссылку на объект типа Journal.

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

5. До JDK 8 при реализации интерфейса нужно были обязательно реализовать все его методы в классе. А сам интерфейс мог содержать только определения методов без конкретной реализации. В JDK 8 были добавлены так называемые "методы по умолчанию". И теперь интерфейсы кроме определения методов могут иметь их реализацию по умолчанию, которая используется, если класс, реализующий данный интерфейс, не реализует метод.

5.1. Метод по умолчанию — это обычный метод без модификаторов, который помечается ключевым словом default. Его не обязательно реализовывать, хотя можно переопределить.

5.2. Также начиная с JDK 8 в интерфейсах доступны статические методы - они аналогичны методам класса. Чтобы обратиться к статическому методу интерфейса также, как и в случае с классами, пишут название интерфейса и метод. У этих методов должна быть реализация.

5.2.1. А вот модификатор final для метода интерфейса не имеет смысла, так как подобный метод нельзя было бы реализовать в применяющем этот интерфейс классе.

5.3. Начиная с Java 9 можно определять в интерфейсе методы с модификатором private. Подобные методы могут использоваться только внутри интерфейса, в котором они определены. То есть когда надо выполнять в интерфейсе некоторые повторяющиеся действия, такие действия можно выделить в приватные методы.

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

6.1. Абстрактные классы используются только тогда, когда есть "is a" тип отношений; интерфейсы могут быть реализованы классами которые не связаны друг с другом. Поэтому с абстрактными классами вы теряете индивидуальность класса, наследующего его; с интерфейсами вы просто расширяете функциональность каждого класса. В Java класс может наследоваться (реализовывать) от многих интерфейсов, но только от одного абстрактного класса.

6.2. Абстрактный класс может реализовывать нестатические методы; интерфейс нет (хотя, начиная с Java 8, может содержать реализацию по умолчанию).

Комментарии


Лучшее   Правила сайта   Вход   Регистрация   Восстановление пароля

Материалы сайта предназначены для лиц старше 16 лет (16+)