Інтерфейс - це громадський прийнятий договір (угода), що визначає деяке поведінка. Навіщо вони потрібні? Наприклад, нехай у нас є посилання, що вказує на список рядків. Припустимо цей у цей список на початку додається безліч елементів, а потім весь список обробляється один раз. Допустимо ми вирішабо наслідувати відому рекомендації і використовувати клас
ArrayList
:
ArrayList<String> list = new ArrayList<>();
Ми написали поведінку програми в 100500 рядків коду, де використовувався цей список рядків, і для оптимізації роботи використовували специфічні методи для класу ArrayList
. Наприклад useCapacity() . Поки рядки додаються до кінця списку, у нас все чудово і швидко працює. Але ось у нас виникла потреба переорієнтувати нашу програму на трохи інший вид робіт, де рядки додаються переважно на початок списку. Для такого характеру навантаження набагато більше підходить LinkedList
. Але якщо ми захочемо перевести свою програму з 100 500 рядків коду на рейки LinkedList
, то нам знадобиться відшукати та прибрати використання специфічних для ArrayList
методів, можливо місцями сильно змінюючи логіку окремих ділянок програми. Якби ми використовували тільки ті методи, які є і в ArrayList
, і в LinkedList
, то нам цього не довелося б робити. Ми б могли лише змінити один рядок коду - оголошення списку:
LinkedList<String> list = new LinkedList<>();
Ми можемо помітити, що було б зручніше винести оголошення загальних методів, для цих класів, в клас-предок, можливо абстрактний, наприклад AbstractList
. У цьому випадку ми могли б оголосити наш список так:
AbstractList<String> list = new ArrayList<>();
І змогли б швидко переключити реалізацію так:
AbstractList<String> list = new LinkedList<>();
Але в цьому випадку, класи, які ми можемо використовувати в нашій програмі, обмежені тільки нащадками класу AbstractList
, навіть якщо є більш відповідні завдання, які не є нащадками AbstractList
, але мають ті ж методи з тією ж поведінкою. Як бути? Саме тому були винайдені інтерфейси . Інтерфейс - це така угода про набір методів та їхню поведінку, яку можуть зобов'язатися дотримуватися абсолютно не пов'язаних класів, дозволяючи посилатися на будь-який з них за допомогою єдиного посилання. Наприклад так:
List<String> list;
list = new ArrayList<>();
list = new LinkedList<>();
list = new AnotherListClass<>();
Навіть якщо AnotherListClass
немає з класами ArrayList
і LinkedList
загальних класів-предків, крім Object
. Хорошим прикладом інтерфейсу є рульове управління автомобіля - у автомобіля є кермо, педалі і коробка передач. У абсолютної більшості автомобілів, ці елементи дотримуються однієї угоди про поведінку. Наприклад, якщо повернути кермо проти годинникової стрілки, автомобіль здійснить поворот вліво, а не збільшить швидкість, незалежно від своєї марки. Якщо ви вмієте використовувати ці елементи керування, ви без особливих зусиль зможете впоратися з будь-яким автомобілем, незалежно від моделі, року випуску, марки і типу двигуна. Більше того, можна уявити ситуацію, в якій зовсім інший вид транспорту (наприклад, космічний корабель) має той самий інтерфейс керування, що й автомобілі. Якщо ви, вміючи керувати автомобілем, потрапите в крісло пілота такого корабля, то зможете не загубитися і в цій ситуації. Ще раз повторимо:
- Інтерфейс це договір (угода) про поведінку.
- Безліч класів, навіть пов'язаних ставленням успадкування, можуть оголосити, що вони зобов'язуються дотримуватися цього договору (імплементація інтерфейсу).
- Винесення опису поведінки в окремий інтерфейс дуже зручно, так як збільшує гнучкість коду, дозволяючи перемикати реалізацію (клас, що імплементує інтерфейс) інтерфейсу, на класи не пов'язані відношенням успадкування.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ