Пользователь vinsler
vinsler
35 уровень
Санкт-Петербург

Interface в Java

Статья из группы Random
Я плохой рассказчик, если у меня нет цели объяснить что-то непонятное кому-то с конкретным запросом, поэтому разбираюсь в простом, ну и за одно напишу об этом тут. Я не придерживаюсь примера обучения JavaRush, как то, что сначала задать вопрос, а потом рассказывать, как это делать. Я сторонник сначала рассказать, а потом спрашивать, как и при рассказе, сначала показать, а потом объяснять.
Interface в Java - 1
BS: Действия == поведение, воспринимайте как синонимы, просто действия более правильно понимаются, это всегда нечто активное, а поведение может ничего не показывать.

interface — интерфейс

Что это? Пример листинга интерфейса (с generics):

public interface Store<T, ID> {
    void add(T t);
    void update(T t, ID i);
    void delete(ID i);
    T findOne(ID i);
    List<T> findAll();
}
Распространенный круд (от CRUD: Create, Read, Update, Delete) интерфейс. Не пугайтесь, все достаточно просто. Интерфейс этот означает, что работа со многими базами данных строится по такому принципу: нужно добавить запись, обновить запись, удалить и найти все записи. Вы еще 100 раз это встретите и сами столько же раз напишете почти такой же интерфейс. Обозначается public, потому что должен реализовываться (implements) классом. Что значит реализовываться классом? Все очень просто: он должен расписать в себе все методы интерфейса. Простейший пример реализации в классе:

void add (T t) {
	bookstore.add(t);
}
Вместо T t, будет подставляться некий дженерик. В двух словах это ТИП переменной, поэтому и обозначается чаще всего как T = Type. В нашем примере, допустим, может быть такой:

void add (Book book) {
	bookstore.add(book);
}
Естественно, на место Book book вы можете подставить любую переменную, которая вам нужна для вашей реализации. Для понимания можно теоретически представить, что T = Object, а поскольку в Java все является Object, можно определить туда также любой ваш класс/переменную. Единственный трабл будет возникать потом — эксепшены, если класс нулевой и т.п. Своими словами — некая программная структура, определяющая отношения между объектами, посредством разделения их на некие поведенческие части. Цель интерфейса — определение функционала для реализации его классом. То есть, описание сигнатур методов. Внутри интерфейса находятся названия методов, возвращающие и входящие значения, и все. Ну можно еще обозначить там какие-то переменные, но они сразу становятся неявно public static final, и могут быть доступны из любой части программы. Интерфейс описывает действия, а поэтому в нем находятся эти самые действия, т.е. функции или методы. Зачем это нужно? Что это упрощает или какие дает преимущества? Упрощение описания действий, поведения. Мы говорим что делать, а как это делать, каждый класс реализует сам. Экономия времени в больших проектах. Интерфейсы создаются в ситуациях, когда мы знаем, что нужно выполнить некоторую задачу, но как это сделать, может отличаться. Интерфейс описывает названия действий — это просто как направление некой абстракции. Хотя могут встречаться и интерфейсы без методов и полей, такие как маркеры, типа Cloneable, Remote и т.п. Возьмем всеми любимый пример с автомобилем. Интерфейс в нем будет описывать возможные действия машины, поворот руля или направление движения, набор скорости, остаток бензина и т.п. То есть те самые действия, которые могут быть у абсолютно любого автомобиля. Другими словами, мы опускаемся в дебри деградации на самый низший уровень создания самого первого автомобиля и своими мозгами додумываем, как он создавался и что у него было. Естественно, мы описываем это абстрактно и только для действий. Что было у самого первого авто? Руль был? Был, значит куда-то поворачивался, направление руля/движения. Колеса были? Да, значит ехал с какой-то скоростью, изменение скорости. Вот и весь интерфейс. Но в целом интерфейсы создаются под какую-то реализацию неких действий. Т.е. мы пишем программу для более конкретных, чем для вообще всего, что только можно придумать. Поэтому и сами интерфейсы будут содержать более четкие и конкретные методы. Конечно же они будут настолько абстрактны, насколько это возможно. Интерфейсы могут быть наследованы друг от друга как классы.

interface MyInterface extends NotMyinterface;
Интерфейсы реализовываются в классах. Реализовывать можно сколько угодно интерфейсов. В отличие от наследования, наследоваться только от одного.

class NewClass extends OldClass implements MyInterface, NotMyinterface;
Т.е. мы придумали какие-то действия, придумали им названия, входящие данные, возвращаемые данные, написали все это в интерфейсе, потом создали класс и добавили наш интерфейс к этом классу, т.е. реализовали наш интерфейс в этом классе. Далее все описаные в интерфейсе методы/функции, должны обязательно иметь реализацию. Ее можно сделать непосредственно в самом интерфейсе, добавив слово default перед методом и написав реализацию прямо в методе, подобно классу. Это стало возможным с 8-й версии Java. Также ее можно сделать в классе, который будет реализовывать этот интерфейс. Ну вот, интерфейс написали, заимплементили в класс, накатили реализацию в классе, можно запускать и тестить. Так же можно почитать в интерфейсах про:
  • Статические методы.
  • Приватные методы. (повтор кода)
  • Переменные/Константы.
  • Вложенные интерфейсы.
Но это уже лучше попозже, да и лишним голову забивать тоже вредно. Интересный вопрос, что такое Volvo? Class or Interface?

line1: Volvo v = new VolvoV2(); 
line2: Volvo v = new VolvoV3(); 
Помимо интерфейсов, стоит продолжить про Абстрактные классы и Классы. Может потом, когда будет еще пара часов свободных. ))) PS: Ребята, всю критику прошу под постом или в ЛС, я прекрасно понимаю, что она есть у всех ))) и мне всегда интересно ее услышать, потому что это повод стать немного лучше и опять таки продолжать двигаться вперед. На этом всем Вам огромное спасибо и удачи в программировании. )))
Комментарии (13)
Чтобы просмотреть все комментарии или оставить свой,
перейдите в полную версию
14 апреля 2021
Добавить бы, что интерфейс может наследоваться от многих интерфейсов* В отличие от класса - может наследоваться только от одного класса родителя, и реализовывать много интерфейсов.
Vermel 19 уровень, Москва
22 апреля 2020
По-моему прекрасно структурированная статья. После всего прочитанного добавляет уверенности в понимании. Спасибо!
Artur 40 уровень, Tallinn Expert
8 июля 2019
Хорошая статья, спасибо тебе, автор! Но у меня после прочтения все-же осталась пара вопросов: 1. Ну можно еще обозначить там какие-то переменные, но они сразу становятся неявно public static final, и могут быть доступны из любой части программы. Например, объявляем в интерфейсе int x; без инициализации, получаем public static final x; равный 0, а потом не можем в классе этой переменной присвоить другое значение, я правильно понял? Или можем один раз? Тогда в каком из классов? Кто первый успел, тот и съел? Или нужно обязательно инициализировать такую переменную тоже в интерфейсе? 2. Далее все описаные в интерфейсе методы/функции, должны обязательно иметь реализацию. Ее можно сделать непосредственно в самом интерфейсе, добавив слово default перед методом и написав реализацию прямо в методе, подобно классу. Этот метод тоже становится public static final как и переменные?
Merlin 3 уровень
18 марта 2019
Пришел сюда из гугла почитать про вложенные интерфейсы и зачем они нужны, а мне тут сказали - попозже)
Павел 22 уровень, Новосибирск
14 февраля 2019
Спасибо за твой труд, для новичков всё доходчиво, термины понятны. Кто льёт критику за такие лекции или чего-нибудь не понимает и злится, мой Вам совет не торопиться. Если Вы ищите в программировании таблетку от всех ваших проблем в жизни, то это не та таблетка, это очень дорогое лекарство и цена ему от 1000 трудочасов, до бесконечности и вот не факт, что это лекарство поможет Вам с вашими проблемами.
Александр Неклеса 41 уровень, Днепр
30 ноября 2018
Норм. Лайк этому господину ) Из статьи не очень понятно, зачем нужны интерфейсы и чем они отличаются от абстрактных классов. В реальных проектах все работает через интерфейсы. У абстрактных классов есть состояние т.е. поля, с которыми могут взаимодействовать методы, у интерфейсов нет полей (статики не в счёт). Зато реализовать(имплементировать) можно много интерфейсов, а от абстрактного класса можно наследоваться только один раз (населедоваться можно только от одного класса). Если у двух разных интерфейсов есть методы с одинаковыми названиями и сигнатурой, НО разными возвращающими типами, то одновременно имплементировать эти интерфейсы нельзя. В интерфейсе можно сделать main метод и всё будет работать (с java 8) Самое главное, там где используются интерфейсы можно использовать совершенно разные не родственные классы, главное, что бы они реализовали интерфейс. Animal a = new Cat(); Animal b = new Dogt(); C Volvo не понятно, т.к это может быть интерфейс, а может класс от которого наследуються Volvo2 и Volvo3 Часто абстрактный класс используется вместе с интерфейсом, реализуя базовую функциональность интерфейса. Например AbstractList
2a.k 18 уровень, Алматы
18 ноября 2018
Nice. Thank you
Taras Sharlay 18 уровень
19 октября 2018
Статья мне ни чего нового не дала, а наоборот - только загрузила блужданиями в голове автора. Совет: Козырять сленгом вообще не стоит, даже если ты живёшь этим. Ты ведь пишешь для других, а не ведёшь свой дневник. Хочешь что-то объяснить - излагай на простом уровне, чтобы каждый, прочитавший и не знавший этой темы, мог понять её. Пока не натренируешься - не надо писать в javarush.
Стас Пасинков 26 уровень, Киев Master
15 октября 2018
сначала так резко зашел с интерфейсов и дженериков)) я думал дальше жесть пойдет) но нет, все нормально, доходчиво))
Rihard1985 33 уровень Master
15 октября 2018
Статья очень понравилась, но хотелось бы рассмотреть еще пост касаемо интерфейсов и абстрактных классов, когда стоит применять интерфейс ,а когда абстрактный класс и чем они отличаются хотя эта тема и является разжеванной, но на собеседованиях говорят любят касаться ее.