Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Властивості класів,,,.docx
Скачиваний:
5
Добавлен:
26.10.2018
Размер:
252.91 Кб
Скачать

3.4.3 Оголошення похідних класів

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