Використання реалізації інтерфейсу

Щоб використовувати клас (скажімо, AttributedImpl), який реалізує деякий інтерфейс, ви можете просто розширити клас У тих випадках, коли такий підхід можливий, він виявляється найпростішим, оскільки при ньому успадковуються всі методи разом з їх реалізацією Однак, якщо вам доводиться підтримувати відразу кілька інтерфейсів або розширювати якийсь інший клас, не виключено, що доведеться вчинити інакше Найчастіше програміст створює обєкт реалізує класу і перенаправляє в нього всі виклики методів інтерфейсу, повертаючи потрібні значення

Ось як виглядає реалізація інтерфейсу Attributed, в якій обєкт AttributedImpl

використовується для наділення атрибутами нашого класу небесних тіл:

import javautilEnumeration

class AttributedBody extends Body implements Attributed

{

AttributedImpl attrImpl = new AtrributedImpl()

AttributedBody() {

super()

}

AttributedBody(String name, Body orbits) {

super(name, orbits)

}

/ / Переспрямувати всі виклики Attributed в обєкт attrImpl

public void add(Attr newAttr)

{ attrImpladd(newAttr) }

public Attr find(String name)

{ return attrImplfind(name) }

public Attr remove(String name)

{ return attrImplremove(name) }

public Enumeration attrs()

{ return attrImplattrs() }

}

Оголошення, відповідно до якого AttributedBody розширює клас Body і реалізує інтерфейс Attributed, визначає контракт Attributed Body Реалізація всіх методів Body успадковується від самого класу Body Реалізація кожного з методів Attributed

полягає в перенаправлення виклику в еквівалентний метод обєкта AttributedImpl і

поверненні отриманого від нього значення (якщо воно є) Звідси випливає, що вам

доведеться включити в клас поле типу AttributedImpl, використовуване при перенаправлення викликів, і ініціалізувати його посиланням на обєкт AttributedImpl

Перенаправлення працює без особливих хитрощів і вимагає значно менших зусиль, ніж реалізація Attributed з нуля. Крім того, якщо в майбутньому зявиться більш вдала реалізація Attributed, ви зможете швидко перейти на неї

46 Для чого застосовуються інтерфейси

Між інтерфейсами і абстрактними класами існує дві важливі відмінності:

Інтерфейси надають деяку різновид множинного спадкоємства, оскільки клас може реалізувати кілька інтерфейсів З іншого боку, клас розширює всього один клас, а не два або більше, навіть якщо всі вони складаються тільки з абстрактних методів

Абстрактний клас може містити часткову реалізацію, захищені компоненти, статичні методи і т д, тоді як інтерфейс обмежується відкритими методами, для яких не задається реалізація, і константами

Ці відмінності зазвичай визначають вибір кошти, яке має застосовуватися для конкретного випадку Якщо вам необхідно скористатися множинним спадкуванням, застосовуються інтерфейси Однак при роботі з абстрактним класом замість перенаправлення методів можна частково або повністю задати їх реалізацію, щоб полегшити успадкування Перенаправлення – досить нудна процедура, до того ж яка загрожує помилками, так що вам варто зайвий раз подумати, перш ніж відмовлятися від абстрактних методів

Проте будь скільки-важливий клас (абстрактний чи ні), призначений для розширення, повинен являти собою реалізацію інтерфейсу Хоча для цього буде потрібно трохи додаткових зусиль, перед вами відкривається цілий спектр нових можливостей, недоступних в інших випадках Наприклад, якби ми просто створили клас Attributed замість інтерфейсу Attributed, реалізованого в спеціальному класі AttributedImpl, то тоді на його основі стало б неможливо побудувати інші корисні класи типу AttributedBody – адже розширювати можна всього один клас Оскільки Attributed є інтерфейсом, у програмістів зявляється вибір: вони

можуть або безпосередньо розширити AttributedImpl і уникнути перенаправлення, або, якщо розширення неможливе, принаймні скористатися перенаправленням для реалізації інтерфейсу Якщо загальна реалізація виявиться невірною, вони напишуть свою власну Ви навіть можете надати декілька реалізацій інтерфейсу для

різних категорій користувачів Незалежно від того, яку стратегію реалізації

вибере програміст, створювані обєкти будуть Attributed

Вправа 41

Перепишіть своє рішення вправи 37 з використанням інтерфейсу, якщо ви не зробили цього раніше

Вправа 42

Перепишіть своє рішення вправи 312 з використанням інтерфейсу, якщо ви не зробили цього раніше

Вправа 43

Чи повинен клас LinkedList з попередніх вправ являти собою інтерфейс Перш ніж відповідати на це питання, перепишіть його з використанням реалізує класу

Вправа 44

Спроектуйте ієрархію класів-колекцій із застосуванням одних інтерфейсів

Вправа 45

Подумайте над тим, як краще подати такі типи (у вигляді інтерфейсів, абстрактних або звичайних класів): 1) TreeNode – для представлення вузлів N-арного дерева 2) TreeWalker – для перебору вузлів дерева в порядку, що визначається користувачем (наприклад, перебір у глибину або в ширину) 3) Drawable – для представлення обєктів, які можуть бути намальовані в графічній системі 4) Application – для програм, які можуть запускатися з графічною робочої поверхні (desktop)

Вправа 46

Як треба змінити умови у вправі 45, щоб ваші відповіді теж змінилися

Глава 5

Лексема, ОПЕРАТОРИ І ВИРАЖЕННЯ

У цьому немає нічого особливого

Все, що від вас вимагається, –

це натискати потрібні клавіші в потрібний момент,

а інструмент буде грати сам

Йоганн Себастьян Бах

У цій главі розглядаються основні будівельні блоки Java-типи, оператори і вирази Ми вже бачили досить багато Java-програм і познайомилися з їх компонентами У цій главі наводиться детальне опис базових елементів

Джерело: Арнольд К, Гослінг Д – Мова програмування Java (1997)

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*