:: Меню ::

Головна
  • Про сайт
  • Введення
  • Середовище програмування VB .NET: Visual Studio .NET
  • Вирази, оператори і передача управління
  • Класи і об'єкти
  •  Спадкоємство і інтерфейси
  • Обробка подій і делегати
  • Обробка помилок в VB .NET
  • Форми Windows, графічний вивід і друк
  • Уведення-виведення
  •  Багатопотокові застосування
  • Підтримка баз-даних в VB .NET
  • Короткий огляд ASP .NET
  • Складки .NET, установка додатків і COM Interop
  • Книга для гостей
    Контакти
    Добавити у вибране

    :: Друзі ::

     
     

    :: Лічильники ::

    = =

     

     

     

     

    Термінологія ООП

    Відправною крапкою у всій термінології ООП є поняття класу. Класом називається шаблон, по якому створюються об'єкти.

    Кожен об'єкт, створений на основі класу, називається екземпляром цього класу. Методи, властивості і процедури подій, визначені усередині класу, називаються членами. Припустимо, ви пишете програму для роботи з інформацією про співробітників компанії. Поза сумнівом, в такій програмі буде визначений клас Employee; кожен екземпляр класу Employee відповідатиме конкретній людині. Члени класу Employee повинні відповідати специфіці вирішуваних завдань (наприклад, у властивості Name зберігатиметься ім'я працівника, а метод Raise-salary використовуватиметься для підвищення зарплати).

    Стосунки між класами в програмах

    У традиційному ООП передбачено три типи стосунків між класами:

    • Використання: безпосередня залежність.
    • Включення: іноді називається агрегацією. Реалізує логічні зв'язки типу «є складовою частиною».
    • Спадкоємство: реалізує логічні зв'язки типу «є окремим випадком».

    У таких мовах, як VB .NET, C# і Java, окрім класичних типів існує четвертий тип стосунків між класами — реалізація інтерфейсу (відношення типу «підтримує»). Суть реалізації інтерфейсу полягає в тому, що для підтримки деяких функціональних можливостей ваш клас переймає на себе зобов'язання, по яких він повинен містити певні члени. Інтерфейси існують в VB починаючи з версії 5 і часто використовуються в VB .NET. В розділі 5 ця тема розглядається набагато докладнішим.

    Повернемося до класичної трійки. Відношення використання, найочевидніше і поширеніше, всього лише означає, що один клас залежить від іншого. У всіх ситуаціях, коли один об'єкт посилає повідомлення іншого об'єкту, можна говорити про залежність між цими об'єктами. У узагальненому випадку клас А використовує клас Би, якщо:

    • член класу А відправляє повідомлення об'єкту класу Б

    або

    • член класу А створює або повертає об'єкти класу Б.

    Постарайтеся звести до мінімуму кількість взаємодіючих класів. Інакше кажучи, уникайте зайвих зв'язків між класами, без яких можна обійтися. Якщо клас А не використовує клас Би, то зміни в класі Б ніяк не відіб'ються на роботі класу А (а отже, модифікація класу Б не стане причиною помилок в класі А!).

    Термін «включення» (агрегація) означає, що об'єкт класу А містить внутрішні об'єкти класу Б.

    На базі включення реалізується методика делегування, коли поставлене перед зовнішнім об'єктом завдання передоручається внутрішньому об'єкту, що спеціалізується на вирішенні завдань такого роду. Агрегація з делегуванням методів була дуже поширеним явищем в колишніх версіях VB, оскільки цей принцип використовувався при створенні нових елементів (пригадаєте, як створювалися нові, спеціалізовані текстові поля — ви розміщували текстове іоле усередині форми призначеного для користувача елементу, а потім запускали программу-мастер, яка автоматично генерувала код делегування).

    Агрегація як і раніше широко використовується в VB .NET, але в багатьох ситуаціях йому на зміну приходить спадкоємство — третій тип стосунків між класами. Спадкоємство вважається за один з чотирьох «наріжних каменів» ООП разом з абстракцією, інкапсуляцією і поліморфізмом. Всі чотири концепції будуть розглянуті в найближчих чотирьох розділах.

    Абстракція

    Абстракцією називається моделювання об'єктів в програмі. Іншими словами, мова йде про імітації реально існуючих об'єктів, що відображає особливості їх взаємодії на навколишньому світі. Так, перша об'єктно-орієнтована мова Simula (http://java.sun.com/people/jag/SimulaHistory.html) розроблявся спеціально для завдань імітації і моделювання. Втім, модні концепції віртуальної реальності виводять принцип абстракції на абсолютно новий рівень, не пов'язаний з фізичними об'єктами. Абстракція необхідна, тому що успішне використання ООП можливе лише в тому випадку, якщо ви зможете виділити змістовні аспекти своєї проблеми.

    Приступаючи до побудови об'єктної моделі, завжди ставте собі питання: які властивості і методи повинні входити в об'єкт, щоб він адекватно моделював ситуацію для вирішення поставленого завдання?

    Інкапсуляція

    У ООП термін «інкапсуляція» означає те, що ми зазвичай називаємо маскуванням даних. Приховуючи дані, ви визначаєте властивості і методи для роботи з ними. Пригадаєте, що мовилося вище, — успішне застосування ООП можливе лише в тому випадку, якщо всі операції з внутрішніми даними об'єкту здійснюються за допомогою обміну повідомленнями. Дані об'єкту зберігаються в полях екземпляра; також часто зустрічається термін «змінні екземпляра». По суті, це одне і те ж, і вибір залежить в основному від того, до якого терміну ви звикли; у цій книзі зазвичай використовується термін «поля екземпляра». Поточний стан об'єкту визначається поточними значеннями полів екземпляра. Не забувайте головне правило: ніколи не надайте прямий доступ ззовні до полів екземпляра (внутрішнім даним об'єкту).

    Повернемося наприклад з об'єктно-орієнтованою програмою для відділу кадрів, в якій ми визначили клас Employee. У змінних класу Еmplоуєе можуть зберігатися наступні відомості:

    • Ім'я.
    • Дата прийому на роботу.
    • Поточна зарплата.

    Щоб змінити значення полів екземпляра, користувачі не звертаються до них безпосередньо, а змінюють властивості і викликають методи типу Rai sesalаrу. Зрозуміло, метод Raisesalary змінюватиме поле з поточною зарплатою, але в нетривіальному класі Employee він може працювати з декількома полями. Наприклад, легко уявити собі метод Rai sesalагу, який ухвалює рішення про підвищення зарплати з урахуванням її поточного рівня, робочого стажу і особистих досягнень працівника. Підведемо підсумок. Інкапсуляція визначає функціональність об'єкту з погляду користувача. Її безпосередніми проявами в VB .NETвыступают члени класу (методи, події і властивості).

    Ризикуючи набриднути частими повтореннями, ми все ж таки ще раз підкреслимо: успішне застосування інкапсуляції можливе, якщо інші частини вашої програми ніколи не дістають прямого доступу до полів екземпляра (змінним) ваших класів. Програма повинна взаємодіяти з ними тільки через допоміжні члени класу. Тільки за наявності закритих даних, недоступних ззовні, об'єкт перетворюється на «чорний ящик» з чіткими правилами поведінки і невідомим внутрішнім устроєм. Обмеження доступу до даних має визначальне значення як для повторного використання, так і для надійності об'єкту при довгостроковому використанні.

    Спадкоємство

    Як приклад спадкоємство уявіть собі класи для окремих категорій працівників (клас Programmer, клас Manager і т. д.). Механізм, використовуваний для створення таких класів на базі класу Empl oyee, називається спадкоємством. У ієрархії спадкоємства клас Employee називається базовим, а клас Programmer — похідним класом. Похідні класи:

    • завжди вирішують більш спеціалізовані завдання, ніж базові класи;
    • містять всі члени базового класу (хоча поведінка цих членів може бути абсолютно іншою).

    Наприклад, метод Raisesalary класу Manager може давати менеджерові велику надбавку до платні, чим метод Raisesalary класу Programmer, при однаковому стажі і особистих показниках.

    Похідний клас може містити нові методи, що не мають аналогів в базовому класі.

    Наприклад, в клас Manager може бути включене нова властивість Secretary.

    Розробники давно хотіли бачити спадкоємство в VB і голосно скаржилися на його відсутність. Не можна сказати, що шум був піднятий на порожньому місці, проте багато хто схильний переоцінювати важливість спадкоємства. Річ у тому, що спадкоємство, якщо гарненько розібратися, всього лише позбавляє програміста від необхідності наново писати готовий код. У спадкоємстві немає ніякої містики — це лише спосіб спростити повторне використання програмної коди. У нашому прикладі класи Employee і Manager володіли рядом схожих рис (наявність дати найму, зарплати і т. д.). Навіщо програмувати властивість Salary в двох місцях, якщо код буде абсолютно однаковим? При повноцінній реалізації спадкоємства використання функціональності базового класу в похідному класі практично не вимагає додаткових зусиль — похідний клас спочатку успадковує всі члени свого предка. Програміст може перевизначити деякі члени базового класу відповідно до специфіки похідного класу. Наприклад, якщо менеджер автоматично отримує 8-процентну надбавку до зарплати, тоді як для більшості працівників надбавка складає всього 4%, метод Raisesalагу класу Manager повинен замінити метод Raisesalary базового класу Employee. З іншого боку, методи ніби Getname в зміні не мають потреби і залишаються в колишньому вигляді.

    Багато впливових теоретиків ООП вважають, що від спадкоємства взагалі стоїть дер-жаться подалі, і рекомендують замінити його використанням інтерфейсів (звичайно, в VB .NET підтримуються обидві можливості). Таке відношення пов'язане з проблемою нестійкості базових класів, яка в VB .NET відійшла на другий план (за подробицями звертайтеся до розділу 5). Використання інтерфейсів замість класичного спадкоємства іноді називається спадкоємством інтерфейсів, тоді як за класичним спадкоємством закріплений термін «спадкоємство реалізації».

    Наприкінці ми хочемо попередити: не використовуйте спадкоємство, якщо ви твердо не упевнені в існуванні логічного зв'язку «є окремим випадком». Наприклад, не створюйте клас Contractor (позаштатний працівник), похідний від Employee, тільки для того, щоб позбавитися від клопоту по дублюванню коди властивостей імені або номера соціального страхування. Позаштатний працівник не є таким, що служить компанії, і бухгалтер, простоти ради що оформив його по загальних правилах, тільки наживе собі неприємності з податковою інспекцією. То ж відноситься і до вас: застосування спадкоємства за відсутності логічного зв'язку «є окремим випадком» приведе до сумних наслідків (див. розділ 5).

    Поліморфізм

    У традиційному трактуванні термін «поліморфізм» (від грецького «багато форм») означає, що об'єкти похідних класів вибирають використовувану версію методу залежно від свого положення в ієрархії спадкоємства. Наприклад, і в базовому класі Employee, і в похідному класі Manager присутній метод для підвищення зарплати працівника. Проте метод Raisesalаrу для об'єктів класу Manager працює не так, як однойменний метод базового об'єкту Employee.

    Класичний прояв поліморфізму при роботі з класом Manager, похідним від Empl oyee, полягає в тому, що при виклику методу по посиланню на Empl oyee буде автоматично вибрана потрібна версія методу (базового або похідного класу). Допустимо, в програмі метод Raisesalary викликається по посиланню на Employee.

    • Якщо посилання на Empl oyee насправді відноситься до об'єкту Manager, буде викликаний метод Ralsesalary класу Manager.
    • Інакше викликається стандартний метод Raisesalary базового класу.

    У Vb5 і Vb6 сенс терміну «поліморфізм» був розширений, і до традиційного полімор-фізму на базі спадкоємства додався поліморфізм на базі інтерфейсів (об'єкт, що реалізовує інтерфейс, викликав метод інтерфейсу замість іншого методу з тим же ім'ям). Об'єкт, що реалізовує інтерфейс Manager, правильно вибере метод Raisesalary залежно від контексту використання.

    У обох випадках об'єкт вибирає метод залежно від отриманого повідомлення. При відправці повідомлення не потрібно знати, до якого класу фактично принадлежіт об'єкт; досить розіслати повідомлення всіх об'єктів Employee і доручити вибір поліморфного методу компілятору.

    Наступний приклад показує, чому поліморфізму надається таке велике значення. Одному з авторів доводилося консультувати компанію, що займалася комп'ютерною обробкою медичних аналізів. Кожного разу, коли в процес тестування включався новий реактив, програмістам доводилося переглядати багато тисяч рядків коди, шукати команди Select Case і додавати в них секції Case для нового реактиву. Варто було пропустити хоч би одну... і нам би не хотілося, щоб цей реактив випробовувався на наших аналізах крові. Звичайно, виправлення багатьох команд Select Case перетворював супровід в справжній кошмар, що вимагає довгого годинника тестування.

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

    Чому? Тому що в головній програмі можна буде використовувати конструкції наступного вигляду:

    For Each reagent in Reagents

    reagent.Method

    Next

    Показаний цикл автоматично працюватиме з новим реактивом, а необхідність в довгих пошуках Sel ect Case відпаде.

    Select Case reagent Case iodine

    ' Дії з йодом Case benzene

    ' Дії з бензолом

    ' І так далі для 100 різних випадків в 100 місцях

    У приведеному вище фрагменті цикл For Each перебирає всі можливі реактиви, і завдяки чарівній властивості поліморфізму компілятор знайде метод, який повинен викликатися для кожного конкретного реактиву. Правильне використання поліморфізму позбавить вас від громіздких команд Select Case, що вибирають потрібну дію залежно від типу об'єкту.

     




    :: Наша кнопка ::

    Отримати код:

    Підтримайте наш сайт і розмістіть нашу кнопку на своєму ресурсі.


    :: Реклама ::

    Скачати безкоштовно програму Microsoft Front Page 2003


    :: Посилання ::

    -


     

     

     


    Copyright ©