Объясните по-простому, на пальцах, зачем и для чего нужны интерфейсы (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 (если их нет в интерфейсе). Оба метода могут использовать только тот набор "средств", которые им доступны (это определяется интерфейсом).