|
|||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||
|
Перехід до використання об'єктів
З давніх
часів в програмуванні використовувалася структурна, процедурно-орієнтована
модель. Спочатку програміст розбирався, що повинна робити програма, а потім
вибирав одне з двох:
Звичайно, багато досвідчених програмістів
не слідували рекомендаціям теоретиків, що виступали за перший
спосіб, і вважали за краще вирішувати практичні завдання комбінацією цих
двох стратегій [ У програмуванні це зазвичай називається зустрічним рухом. ]. Між ООП
і процедурно-орієнтованим програмуванням існують дві важливі відмінності:
Виникає очевидне питання:
по яких критеріях виділяти класи в програмі? Для цього є хороше
емпіричне правило, яке пов'язує компоненти об'єктної моделі з
частинами мови. Класи відповідають іменникам в постановці завдання. У нашому
прикладі центральне місце займає іменник «працівник» (Employee). Методи
об'єктів відповідають дієсловам — наприклад, працівникові можна підвищити зарплату
(метод Raisesalary). Властивості відповідають додавальним, таким, що
описує іменники. Зрозуміло, ця відповідність лише намічає контури
об'єктної моделі. Тільки практичний досвід допоможе вам вирішити, які іменники,
дієслова і прикметники важливі, а які є другорядними. Зараз варто повторити
золоте правило програмування, що аніскільки не змінилося з переходом
на ООП: будьте простіше. Використання простих класів помітно спрощує
об'єктно-орієнтоване програмування. Клас з простий внутрішньою структурою
і невеликим числом зовнішніх зв'язків простіше зрозуміти, а отже, і запрограмувати. Опис
логічних зв'язків між класами грає в ООП настільки важливу роль, що з'явилася
ціла наука про побудову діаграм, що ілюструють стосунки між
класами. Найчастіше для опису логічних зв'язків застосовується мова UML (Uniform Model
Language). Засоби побудови діаграм входять в багато систем автоматизованої
розробки програм — такі, як Microsoft Visual Modeler і Visio, а також Rational
Rose компанії Rational Software (Visual Modeler входить в деякі версії VS
.NET). Деякі
пакети на підставі діаграми автоматично генерують базовий код класів.
За загальними відомостями про UML ми рекомендуємо звертатися на web-сайт Rational (www.rational.com/uml).
Отже, ви
вирішили, які класи повинні входити у ваш проект. На наступному етапі побудови
об'єктної моделі розглядаються конкретні екземпляри цих класів. Спробуйте
відповісти на три питання:
У полях екземпляра зберігається інформація
про операції, що виконуються об'єктом; деякі поля можуть використовуватися
для зберігання інформації про історію існування об'єкту. В сукупності ці
відомості визначають стан об'єкту. Стан об'єкту схильний до
частих змін, але, як було сказано вище, будь-які зміни в стані об'єкту
в результаті зовнішніх дій повинні відбуватися тільки в результаті отриманих
повідомлень. Поточний стан
об'єкту не забезпечує його однозначної ідентифікації. Два об'єкти можуть знаходитися
в однаковому стані, однаково реагувати на зовнішні дії, але при
цьому вони все одно залишаються різними об'єктами (як два масиви з однаковим
вмістом). Таким чином, повинен існувати якийсь критерій, по якому
об'єкт можна відрізнити від інших схожих об'єктів. До поведінки об'єкту відноситься
інформація про те, що він робить в даний момент і що він теоретично може
зробити в майбутньому. У VB .NET поведінка об'єкту визначається його властивостями,
методами і подіями. Поза
сумнівом, ці три характеристики впливають один на одного, і ця обставина повинна
враховуватися в коді класу. Наприклад, поведінка об'єкту залежить від його поточного
стану: заблоковане текстове поле поводиться зовсім не так, як доступне, і про
це слід пам'ятати при проектуванні класу.
На перший
погляд класи ООП і пов'язані з ними методи і властивості мають багато загального з
процедурним підходом і модульною будовою програм. Ключова відмінність полягає
в наступній:
Класом є шаблон для створення об'єктів, стан яких змінюється
з часом. Виглядає
дуже абстрактно? І начебто не має ніякого відношення до програмування VB?
Пригадаєте панель елементів Visual Basic. У колишніх версіях VB кожна кнопка панелі
створювала об'єкт, що є екземпляром класу відповідного елементу. А якби панель елементів,
готова у будь-який момент створити нове текстове поле або кнопку по вашому
запиту, кудись зникла? Тільки представте, якими складними стануть програми VB,
якщо кожне текстове поле доведеться оформляти у вигляді окремого модуля! До
речі кажучи, один модуль не можна підключити до програми двічі, тому
створення форми з двома однаковими текстовими полями зажадає досить витонченого
програмування.
Завдяки існуванню панелі елементів VB завжди був об'єктно-орієнтованою
мовою. Починаючи з версії 4 в нім з'явилася можливість створювати деякі типи
об'єктів. Але тільки в VB .NET програміст може визначати класи для будь-яких
об'єктів і повною мірою використовувати засоби ООП на тому ж рівні,
що і в C++ і С#. Більш того, всі мови .NET забезпечують приблизно рівну ефективність
п$і роботі з класами.
У VB .NET,
як і в колишніх версіях VB, об'єкти створюються ключовим словом New (виняток
становлять рядки і масиви — для створення цих об'єктів передбачений скорочений
запис). Розглянемо
практичний приклад — в .NET Framework входить корисний клас Random для роботи
з випадковими числами. По своїх можливостях цей клас перевершує функцію
Rnd, збережену в мові для забезпечення зворотної сумісності. Наприклад, клас
Random дозволяє заповнити байтовий масив випадковими числами від 0 до 255 або
згенерувати позитивне випадкове число в заданому інтервалі. Проте Random
— не функція, а клас, методи якого викликаються з вказівкою конкретного екземпляра.
А для цього необхідно заздалегідь створити екземпляр (простіше кажучи, об'єкт)
класу Random.
Зробити це можна декількома способами, і в будь-якому варіанті використовується
ключове слово New. Найнаочніший, хоча і не найкомпактніший спосіб полягає у відділенні
оголошення класу від виклику New: Dim arandomlnstance As Random ' Оголошення arandomlnstance = New Random() '
Створення екземпляра Багато програмістів вважають за
краще використовувати скорочений запис: Dim arandomlnstance As New Random ' Екземпляр створюється
при оголошенні Ця команда
еквівалентна приведеному вище фрагменту; у ній використовується така можливість
VB .NET, як ініціалізація змінних при оголошенні. На мові
ООП метод New називається конструктором, оскільки він призначений для
створення (конструювання) екземплярів класу. У колишніх
версіях VB між повною і скороченою формою виклику конструктора існували
тонкі відмінності, пов'язані з тим, що при скороченому записі створення об'єкту
відкладалося до моменту першого використання. У VB .NET ця особливість була
виключена. Деякі програмісти (що
особливо працюють на С# і Java) віддають перевагу третьому варіанту
синтаксису, який виглядає як комбінація перших два: Dim foo As Random = New Random() ' У стилі C#/java Він нічим
не відрізняється від другого варіанту синтаксису. Метод New
дозволяє конструювати об'єкти в будь-якому виразі VB .NET, якщо результат відповідає
контексту. Наступна команда VB .NET цілком допустіма
(хоча зрозуміти її непросто, тому використовувати подібний стиль програмування
не рекомендується): Consolе.WriteLi
net New Random().Next()) Втім,
подібні конструкції можуть зустрітися в чужих програмах, які вам доведеться
супроводжувати. Особливо часто вони використовуються програмістами з досвідом роботи
на C++/java. Створивши екземпляр
класу Random, ви можете користуватися його методами і властивостями за допомогою знайомого
«точкового» синтаксису. Бібліотека .NET Framework містить безліч
класів; технологія Intellisense завжди нагадає вам, що можна зробити з тим
або іншим екземпляром класу (мал. 4.1).
Мал.
4.1. Підказка
Intellisense для класу Random
Наприклад, на відміну від функції Rnd з колишніх версій VB вам не доведеться
додатково обробляти числа від 0 1, щоб отримати випадкове позитивне число в
заданому інтервалі. Вам знадобилося випадкове ціле від 1 до 6? Скористайтеся
наступною конструкцією: Dim arandomlinstance As New Random() Dim die As Integer die =aRandomInstance.Next(1.6) Console.WriteLine(die) Доступ до засобів
класу зазвичай здійснюється через конкретний екземпляр, проте у цього
правила є виключення. Річ у тому, що деякі можливості реалізуються на
рівні класу, а не окремих об'єктів. В розділі 3 ми зустрічалися з класом Math
і використанням конструкцій Math . PI і Math . Sin( ) без виклику методу New.
Члени, що належать класу в цілому, а не його окремим екземплярам, називаються
загальними (shared). До загальних членів можна звертатися як по імені класу,
так і по імені об'єктної змінної, оголошеної з відповідающим
типом. Припустимо, у вас є клас Ваr із загальним методом Foo. Метод Foo може
бути викликаний будь-яким. з приведених нижче способів: Ваги.Foo() Dim test As
Bar test.Foo()
Конструктори,
що параметризуються
На перший погляд
конструктор New працює так само, як в попередніх версіях VB. Насправді змінилося дуже
багато що, і найпринциповіша зміна полягає в тому, що при
виклику New тепер можуть передаватися параметри. Як ви незабаром побачите, в призначених
для користувача класах перевизначена версія New заміщає подію Initial
ize з колишніх версій VB, яке не підтримувало параметрів. Наприклад,
для класу Random визначено дві версії конструктора. Перша версія викликається
без параметрів, як показано вище. В цьому випадку ви отримуєте випадкові числа,
отримані в результаті випадкової ініціалізації генератора за свідченнями системного
годинника. Інша версія виглядає так: Dim arandomlnstance As Random arandomlnstance
= New Random(42) Ця версія класу
Random генерує одну і ту ж послідовність випадкових чисел, що починається
з числа 42 (ця можливість абсолютно необхідна в процесі відладки). Як не дивно, поява
конструкторів, що параметризуються, в VB зробила для повноцінної реалізації
ООП чи не більше, ніж підтримка спадкоємства. Якщо спадкоємство ще можна замінити
в програмі іншими засобами (зазвичай агрегацією), то компенсувати відсутність
конструкторів, що параметризуються, набагато важче. Конструктори,
що параметризуються, потрібні перш за все для того, щоб запобігти
випадковому створенню об'єкту в невизначеному стані. У колишніх версіях VB це
завжди породжувало масу проблем, оскільки подія Initialize викликалася без
параметрів. Залишалося лише слідувати загальноприйнятій схемі — включати в клас функцію
ініціалізації об'єктів (зазвичай цій функції привласнювалося ім'я Create) і сподіватися на те,
що пользовать класу не забуде викликати цю функцію. Інакше об'єкт не ініціалізувався,
а поля екземпляра зберігали значення за умовчанням, що приводило до появи
тонких, невловимих помилок. У VB .NET,
як у всіх об'єктно-орієнтованих мовах, об'єкт створюється тільки конструктором.
Більш того, нижче буде показано, як зажадати обов'язкової передачі
параметрів при виклику конструктора — це гарантує, що об'єкт не буде створений
в невизначеному стані.
|
|
|||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||