Объясните по-простому, на пальцах, зачем и для чего нужны интерфейсы (Java)? Все эти заумные книжные определения и формулировки, ясности совсем не прибавляют.
Ответ
Общее определение:
Интерфейс — это совокупность методов и правил взаимодействия элементов системы. Другими словами, интерфейс определяет как элементы будут взаимодействовать между собой.
Интерфейс двери — наличие ручки;
Интерфейс автомобиля — наличие руля, педалей, рычага коробки передач;
Интерфейс дискового телефона — трубка + дисковый набиратель номера.
Когда вы используете эти "объекты", вы уверены в том, что вы сможете использовать их подобным образом. Благодаря тому, что вы знакомы с их интерфейсом.
В программировании что-то похожее. Почему графическую часть программы часто называют интерфейсом? Потому, что она определяет каким образом вы сможете использовать основной функционал, заложенный в программе.
"Интерфейс определяет каким образом мы можем использовать объект" - перенесем эту мысль в плоскость программирования.
Предположим, у вас в программе есть следующие типы:
// несколько базовых интерфейсов, они пустые,
// т.к. их наполнение на данный момент не существенно
interface Rul {}
interface Pedal {}
interface Kpp {}
// интерфейс описывает взаимодействие с автомобилем - т.е. его интерфейс
// предоставляет другим объектам доступ к рулю и педалям
// (по сути этот интерфейс соответствует автомобилю с коробкой автоматом)
interface Car {
Rul getRul();
Pedal[] getPedali();
}
// этот интерфейс расширяет базовый
// и предоставляет доступ еще и к коробке передач
interface CarWithKPP extends Car {
Kpp getKpp();
}
// а здесь у нас сам автомобиль
// реализации методов опущены т.к. не существенно
class SomeCar implements CarWithKpp {...}
а сейчас посмотрим, как можно пользоваться тем, что у нас есть:
// создаем новый объект
SomeCar instance = new SomeCar();
// делаем какие-то действия над объектом
testAction1(instance);
testAction2(instance);
Как видите, используем мы их одинаково, но суть кроется в реализации методов:
void testAction1(CarWithKpp c) {
c.getRul(); // можно
c.getPedali(); // можно
c.getKpp(); // можно
}
void testAction2(Car c) {
c.getRul(); // можно
c.getPedali(); // можно
c.getKpp(); // нельзя, ошибка компиляции. этот метод не определен в интерфейсе Car
}
С одной стороны, тот факт, что SomeCar наследует интерфейс CarWithKpp (а посредством последнего еще и Car), позволяет нам использовать его для работы с методами testAction1, testAction2. Интерфейсы, которые реализованы (имплементированы) в классе SomeCar — предоставляют доступ к правильному его использованию. А еще использование интерфейса в сигнатуре метода гарантирует, что вы получите именно тот тип, который вам нужен.
Обратная сторона медали состоит в том, что интерфейс накладывает ограничения на использование класса. Примером этому является то, что в методе testAction2 получить доступ к методу getKpp уже невозможно. Таким образом, можно скрыть методы и свойства, которые объявлены в интерфейсе CarWithKpp, а также методы, объявленные в классе SomeCar (если их нет в интерфейсе). Оба метода могут использовать только тот набор "средств", которые им доступны (это определяется интерфейсом).
Комментариев нет:
Отправить комментарий