Розширення класів: коли і як

Можливість створення розширених класів – одне з головних достоїнств обєктно-орієнтованого програмування Коли ви розширюєте клас, щоб наділити його новими функціями, то при цьому виникає так зване відношення подібності (IsA relationship) – розширення створює новий тип обєктів, які подібні вихідного класу Відношення подібності істотно відрізняється від ставлення приналежності (HasA relationship), при якому один обєкт користується іншим для зберігання інформації про свій стан або для виконання своїх функцій – йому належить посилання на даний обєкт

Давайте розглянемо приклад Припустимо, у нас є клас Point, представляє точку в двовимірному просторі у вигляді пари координат (x, y) Клас Point можна розширити і

створити на його основі клас Pixel для представлення кольорового пікселя на екрані Pixel подібний до Point все, що справедливо по відношенню до простої точці, буде справедливо і по відношенню до пікселя В клас Pixel можна включити механізм для зберігання інформації про колір пікселя або посилання на обєкт-екран, на якому знаходиться піксель Піксель подібний до точці (тобто є її окремим випадком), так як він являє собою точку на площині (екрані) з розширеним контрактом (для нього також визначено поняття кольору і екрану)

З іншого боку, коло не можна вважати окремим випадком точки Хоча в принципі коло можна описати як точку, що має радіус, він має низку властивостей, які відсутні у точки Наприклад, якщо у вас є метод, який поміщає центр деякого прямокутника в заданій точці, то який сенс матиме цей метод для кола Кожному колу належить центр, який є точкою, але коло не є крапкою з радіусом і не повинен представлятися у вигляді підкласу Point

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

Налагодження звязків подібності та приладдя – завдання нетривіальне і яка загрожує ускладненнями Наприклад, при використанні обєктно-орієнтованих засобів для проектуванні бази даних про працівників фірми можна піти по найбільш очевидному і загальноприйнятій шляху – створити клас Employee, в якому зберігаються загальні відомості для всіх працівників (наприклад, імя та табельний номер) і потім розширити його для роботи з певними категоріями працівників – Manager, Engineer, FileClerk і т д

Такий варіант не підходить в реальній ситуації, коли один і той же особа виконує кілька функцій Скажімо, інженер може одночасно бути менеджером групи і, отже, присутні відразу в двох якостях Візьмемо інший приклад – аспірант може бути і учням, і викладачем

Більш гнучкий підхід полягає в тому, щоб створити клас Role (функція працівника) і розширити його для створення спеціалізованих класів – наприклад, Manager У цьому випадку можна змінити клас Employee і перетворити його в набір обєктів Role Тоді конкретну особу може бути повязано з постійно змінюються набором функцій усередині організації Від концепції менеджер є працівником ми переходимо до концепції Менеджер є функцією, при якій працівникові може належати функція менеджера поряд з іншими функціями

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

Джерело: Арнольд К, Гослінг Д – Мова програмування 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>

*

*