|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Оголошення похідних класівC++Builder дає можливість оголосити похідний клас, який успадковує властивості, дані, методи і події всіх своїх попередників в ієрархії класів, а також може оголошувати нові характеристики і перенавантажувати деякі з успадкованих функцій. Успадковувавши вказані характеристики базового класу, можна змусити породжений клас розширити, звузити, змінити, знищити або залишити їх без змін. Спадкоємство дозволяє повторно використовувати код базового класу в екземплярах похідного класу. Концепція повторного використання має паралель в живій природі: ДНК можна розглядати як базовий матеріал, який кожна породжена істота повторно використовує для відтворення свого власного вигляду. Лістинг 3.5 ілюструє узагальнений синтаксис оголошення похідного класу. Порядок перерахування секцій відповідає розширень привілеїв захисту і зон видимості укладених в них елементів: від найбільш обмежених до найдоступніших. class className: [^спецификатор доступу;”] parentClass { <0б'явленія дружніх класів> private: <приватні члени даних> <приватні конструктори> <приватні методи> protected: <захищені члени даних> <захищені конструктори> <захищені методи> public: <загальнодоступні властивості> <загальнодоступні члени даних> <загальнодоступні конструктори> <загальнодоступна деструкція> <загальнодоступні методи> _published: <загальновідомі властивості> <загальновідомі члени даних> <Оголошення дружніх функцій> Лістинг 3.5. Оголошення похідного класу. Відзначимо появу нової секції з ключовим словом _ published - доповнення, яке C++Builder вводить в стандарт ANSI C++ для оголошення загальновідомих елементів компонентних класів. Ця секція відрізняється від загальнодоступної тільки тим, що компілятор генерує інформацію RTTI про властивості, членів даних і методи об'єкту і C++Builder організовує передачу цій інформації Інспекторові об'єктів під час виконання програми. В розділі 6 ми зупинимося на цьому детальніше. Окрім здатності виконувати своє безпосереднє завдання об'єктні методи отримують певні привілеї доступу до значень властивостей і даних інших класів. Коли клас породжується від базового, всі його імена в похідному класі автоматично стають приватними за умовчанням. Але його легко змінити, вказавши наступні специфікатори доступу базового класу: • private. успадковані (тобто захищені і загальнодоступні) імена базового класу стають недоступними в екземплярах похідного класу. • public. Загальнодоступні імена базового класу і його попередників будуть доступними в екземплярах похідного класу, а всі захищені залишаться захищеними. Можна породжувати класи, які розширюють можливості базового класу: він цілком прийнятний для вас, проте містить функцію, що вимагає невеликого доопрацювання. Написання наново потрібної функції в похідному класі є марною тратою часу. Замість цього треба повторно використовувати код в базовому класі, розширюючи його настільки, наскільки це необхідно. Просто перевизначите в похідному класі ту функцію базового класу, яка вас не влаштовує. Так само можна створювати класи, які обмежують можливості базового класу: він цілком прийнятний для вас, але робить щось зайве. Розглянемо застосування методик розширення і обмеження характеристик на прикладі створення різновидів об'єкту кнопки - типових похідних класів, що отримуються при спадкоємстві базового компонента TButtonControl із Бібліотеки Візуальних Компонентів C++Builder. Кнопки різного вигляду часто з'являтимуться в діалогових вікнах графічного інтерфейсу ваших програм. Мал. 3.1 показує, що базовий клас TButtonControl здатний за допомогою батьківського методу Draw відображати кнопку у вигляді двох вкладених прямокутників: зовнішньої рамки і внутрішньої закрашеної області. Щоб створити просту кнопку без рамки (мал. 3.2), потрібно побудувати похідний клас SimpleButton, використавши як батьківського TButtonControl, і перенавантажувати метод Draw з обмеженням його функціональності (Лістинг 3.6) class SimpleButton: public: TButtonControl { public: SimpleButton(int x int y);
void Draw(); -SimpleButton() { } }; SimpleButton::SimpleButton(int x int y): TbuttonControl(x, у) { }
void SimpleButton::Draw() { ; outline->Draw(); } Лістинг 3.6. Обмеження характеристик базового класу. Єдине завдання конструктора об'єкту для SimpleButton - викликати базовий клас з двома параметрами. Саме перевизначення методу SimpleButton:: Draw () запобігає виведенню рамки кнопки, що обводить (як відбувається в батьківському класі). Природно, щоб змінити код методу, треба вивчити його з початкового тексту базового компоненту TButtonControl. Тепер створимо кнопку з назвою пояснення (мал. 3.3). Для цього потрібно побудувати похідний клас TextButton з базового TButtonControl, і перенавантажувати метод Draw. Рис. 3.3. Кнопка з текстом, розширенням його функціональності. Лістинг 3.7 показує, що об'єкт назви title класу Text створюється конструктором TextButton, а метод SimpleButton:-.Draw () відображає його. : class Text { public: Text(int x, int у char* string) { } void Draw() { } };
class TextButton: public: TButtonControl { Text* title; public: TextButton(int x int у, char* title);
void Draw(); -TextButton() { }); TextButton::TextButton(int x int у, char* caption) TButtonControl(x, у){ title = new Text(x, у, caption); }
void TextButton::Draw () { TextButton::Draw(); title->Draw(); } Лістинг 3.7. Розширення характеристик базового класу. На закінчення розділу з викладом методики розробки базових і похідних класів приводиться фрагмент C++ програми (Лістинг 3.8), в якій оголошена ієрархія класів двох простих геометричних об'єктів: кола і циліндра. Програма складена так, щоб внутрішні значення змінних градіусів кола і h-висоти циліндра визначали параметри створюваних об'єктів. Базовий клас Circle моделює коло, а похідний клас Cylinder моделює циліндр. class SimpleButton: public: TButtonControl { public: SimpleButton (int x int y);
void Draw(); -SimpleButton() { } ); SimpleButton::SimpleButton(int x int y): TButtonControl(x, у) { }
I void SimpleButton::Draw() I { i outline->Draw();
1) Лістинг 3.7 показує, що об'єкт назви title класу Text створюється конструктором TextButton, а метод SimpleButton:: Draw () відображає його. const double pi = 4 * atan(l);
class Circle { protected: double r; public: Circle (double rVal =0): r(rVal){}
void setRadius(double rVal) { r = rVal; }
double getRadiusO { return r; } .double Area() { return pi*r*r; }
void showData(); };
class Cylinder: public Circle { protected: double h; public: Cylinder(double hVal = 0 double rVal = 0) : getHeight(hVal), Circle(rVal) { }
void setHeight(double hVal) { h = hVal; }
double getHeight() { return h; }
double Area() { return 2*Circle::Crea()+2*pi*r*h; }
void showData();
void Circle::showData() { cout “ "Радіус кола = " “ getRadius() “ endl “ "Площа круга = " “ Area O “ endl “ endl; }
void Cylinder::showData() { cout “ "Радіус підстави = " “ getRadius() “ endl “ "Висота циліндра = " “ getHeight() “ endl “ "Площа поверхні = " “ Area () “ endl; }
void main() { Circle circle(2); Cylinder cylinder(10, 1); circle.showData (); cylinder.showData(); Лістинг 3.8. Проста ієрархія класів кола і циліндра. Оголошення класу Circle містить єдиний член даних r, конструктор і ряд методів. При створенні об'єкту конструктор ініціалізував член даних r початковим значенням радіусу кола. Відзначимо новий синтаксис конструктора: при виклику він може звернутися до конструктора базового класу, а також до будь-якого члена даних, вказаного після двокрапки. У нашому випадку член даних r "створюється" зверненням до нього з параметром rval і ініціалізувався нульовим значенням. Метод setRradius встановлює, а getRadius повертає значення члена даних r. Метод Area повертає площа круга. Метод showData видає значення радіусу кола і площі круга. Клас Cylinder, оголошений як похідний від Circle, містить єдиний член даних h, конструктор і ряд методів. Цей клас успадковує член даних г для зберігання радіусу підстави циліндра і методи setRadius і getRadius. При створенні об'єкту конструктор ініціалізував члени даних г і h початковими значеннями. Відзначимо новий синтаксис конструктора: у нашому випадку член даних h ініціалізувався значенням аргументу hVal, а член даних г - викликом конструктора базового класу Circle з аргументом rVal. Функція setHeight встановлює, а getHeight повертає значення члена даних h. Circle::Area перенавантажує успадковану функцію базового класу, щоб тепер повертати площу поверхні циліндра. Функція showData видає значення радіусу підстави, висоти і площі поверхні циліндра. Функція main створює коло circle класу Circle з радіусом 2 і циліндр cylinder класу Cylinder з висотою 10 і радіусом підстави 1, а потім звертається до showData для виведення параметрів створених об'єктів: Радіус кола = 2 Площа круга = 12.566 Радіус підстави = 1 Висота циліндра = 10 Площа поверхні = 69.115 Поліморфізм Слово поліморфізм від грецьких слів poly (багато) і morphos (форма) означає множинність форм. Поліморфізм - це властивість споріднених об'єктів (тобто об'єктів, класи яких є похідними від одного батька) поводитися по-різному залежно від ситуації, що виникає у момент виконання програми. В рамках ООП програміст може впливати на поведінку об'єкту тільки побічно, змінюючи вхідні в нього методи і додаючи нащадкам відсутні у батька специфічні властивості. Для зміни методу необхідно перенавантажувати його в нащадку, тобто оголосити в нащадку однойменний метод і реалізувати в нім потрібні дії. В результаті в об'єкті-батько і об'єкті-нащадок діятимуть два однойменні методи, що мають різну кодову реалізацію і, отже, що додають об'єктам різну поведінку. Наприклад, в ієрархії споріднених класів геометричних фігур (крапка, пряма лінія, квадрат, прямокутник, коло, еліпс і так далі) кожен клас має метод Draw, який відповідає за належний відгук на подію з вимогою намалювати цю фігуру. Завдяки поліморфізму, нащадки можуть перенавантажувати загальні методи батька з тим, щоб реагувати специфічним чином на одну і ту ж подію. Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.01 сек.) |