Ответы на билеты (Билет 20 (2))

Посмотреть архив целиком

Билет №20

  1. Наследование. Понятия и определения. Пример.

  2. Интерфейсы. Понятия и определения. Пример использования.

  3. Конструкторы производных классов.


  1. Наследование – это свойство объекта, которое заключается в том, что характеристики одного объекта (объекта-предка) могут передаваться другому объекту (объекту-потомку) без повторного их описания. Наследование упрощает описание объектов.


Наследование (inheritance) — это процесс, посредством которого один объект

может приобретать свойства другого. Точнее, объект может наследовать основные свойства другого объекта и добавлять к ним черты, характерные только для него. Наследование является важным, поскольку оно позволяет поддерживать концепцию иерархии классов (hierarchical classification). Применение иерархии классов делает управляемыми большие потоки информации. Например, подумайте об описании жилого дома. Дом — это часть общего класса, называемого строением. С другой стороны, строение — это часть более общего класса — конструкции, который является частью еще более общего класса объектов, который можно назвать созданием рук Человека. В каждом случае порожденный класс наследует все, связанные с родителем, качества и добавляет к ним свои собственные определяющие характеристики. Без использования иерархии классов, для каждого объекта пришлось бы задать все характеристики, которые бы исчерпывающе его определяли. Однако при использовании наследования можно описать объект путем определения того общего класса (или классов), к которому он относится, с теми специальными чертами, которые делают объект уникальным.



Пример: Наследование свойств и базовая концепция классов являются основополагающими для организации пути познания. Например, сельдерей — член класса овощей, которые являются частью класса растений. В свою очередь, растения являются живыми организмами и так далее. Без иерархии классов систематизация знаний была бы невозможна.


// Определение базового класса

class В {

int i;

public:

void set_i(int n) ;

int get_i();

} ;



// Теперь объявим производный класс, наследующий этот базовый:

// Определение производного класса

Class D: public В {

int j;

public:

void set_j (int n) ;

int raul () ;






Законченная программа, в которой используются классы

В и D:


// Простой пример наследования

#include

using namespace std;


// Определение базового класса

class В {

int i;

public:

void set_i(int n) ;

int get_i ( ) ;


// Определение производного класса

class D: public В {

int j;

public:

void set_j (int n) ;

int mul () ;


// Задание значения i в базовом классе

void B::set_i(int n}

{

i = n;

}


// Возвращение значения i в базовом классе

int В: :get_i ()


return i;


// Задание значения j в производном классе

void D: :set_j (int n)

t

j = n;


// Возвращение значения i базового класса и j — производного

int D: :mul (}


// производный класс может

// вызывать функции-члены базового класса

return j * get_i(};

}

int main ( )

{

D ob;

ob.set_i (10) ; // загрузка i в базовый класс

ob.set_j(4); // загрузка j в производный класс

cout ≪ ob.mul(); // вывод числа 40

return 0;

1

2. Интерфе́йс (от лат. inter — между и лат. faceповерхность) — это семантическая и синтаксическая конструкция в коде программы, используемая для специфицирования услуг, предоставляемых классом или компонентом.

Интерфейс определяет границу взаимодействия между классами или компонентами, специфицируя определенную абстракцию, которую осуществляет реализующая сторона. В отличие от большинства других видов интерфейсов, интерфейс в ООП является строго формализованным элементом объектно-ориентированного языка и, в качестве семантической конструкции, широко используется кодом программы. К примеру, интерфейс «Cloneable» может описать абстракцию клонирования (создания точных копий) объектов, специфицировав метод «Clone». Тогда любой класс, способный создать свою копию, может задекларировать себя как Cloneable и предоставить метод Clone. Причем вызывающей стороне достаточно знать только описание интерфейса. Таким образом, интерфейсы позволяют рассоединить части программной системы в модули без взаимной зависимости кода.

С одной стороны, интерфейс — это контракт, который обязуется выполнить класс, реализующий его. Один класс может реализовать несколько интерфейсов одновременно.
С другой стороны,
интерфейс — это тип данных, потому что его описание достаточно четко определяет свойства объектов, чтобы наравне с классом типизировать переменные.

Роль интерфейсов в C++ выполняют абстрактные классы.

Интерфейс трактуется как набор всех потенциально возможных операций, которые могут быть выполнены объектом по заявкам клиентов. Вводится отношение "объект удовлетворяет интерфейсу". Оно имеет место, если рассматриваемый объект может быть указан как целевой в любой возможной заявке, которая адекватна данному интерфейсу. Интерфейсы могут иметь атрибуты. Наличие атрибута логически эквивалентно объявлению пары функций доступа: для извлечения и для установки значения атрибута, соответственно.

Интерфейсы в модели типизируются. Под типом данного интерфейса понимается такой тип, которому удовлетворяет любой объект, удовлетворяющий рассматриваемому конкретному интерфейсу.

На интерфейсы распространяется действие механизмов наследования. Интерфейс, наследующий свойства другого интерфейса, называется производным от этого другого интерфейса, который, в свою очередь, называется базовым по отношению к нему. В производном интерфейсе могут объявляться новые элементы или переопределяться наследуемые. Интерфейс может быть производным от нескольких базовых интерфейсов. На множестве определенных интерфейсов могут, таким образом, поддерживаться иерархии отношений наследования. Наследование интерфейсов есть композиционный механизм, позволяющий объекту поддерживать множественные интерфейсы. Главный (principal) интерфейс является наиболее специализированным интерфейсом, поддерживаемым объектом. Этот интерфейс состоит из всех операций в транзитивном замыкании графа наследования интерфейсов.

Введено понятие реализации объекта, которое трактуется следующим образом. Метод представляет собой программу, исполняемую для реализации сервиса. С методом связаны формат метода, определяющий набор исполнительных механизмов для интерпретации метода, и исполнительный механизм - абстрактная машина, интерпретирующая методы определенных форматов. Реализация объекта представляет собой определение, содержащее информацию, необходимую для создания объекта и для участия объекта в обеспечении надлежащего набора сервисов. Реализация обычно включает определения методов, оперирующих состоянием объекта.

Понятие интерфейса

Из предыдущих глав вы уже знаете, что собой представляет объект. Представьте, что получится, если из объекта убрать поля и код всех методов. Останется лишь интерфейс — заголовки методов и описания свойств. Схематично понятие интерфейса можно представить в виде формулы:

Интерфейс = Объект - Реализация

В отличие от объекта интерфейс сам ничего "не помнит" и ничего "не умеет делать"; он является всего лишь "разъемом" для работы с объектом. Объект может поддерживать много интерфейсов и выступать в разных ролях в зависимости от того, через какой интерфейс вы его используете. Совершенно различные по структуре объекты, поддерживающие один и тот же интерфейс, являются взаимозаменяемыми. Не важно, есть у объектов общий предок или нет. В данном случае интерфейс служит их дополнительным общим предком.

// Использование виртуальной функции для определения интерфейса

#include

using namespace std;


class area {

double dim1, dim2; // размеры фигуры

public:

void setarea(double d1, double d2)

dim1 = d1;

dim2 = d2;

void getdim(double sdl, double &d2)

d1 = dim1;

d2 = dim2;

virtual double getarea

cout << "Вам необходимо подменить эту функции\n";

return 0;


class rectangle: public area {

public:

double getarea;

double dl, d2;

getdim{dl, d2);

return dl * d2;

}

};

class triangle: public area {

public:

double getarea()

double dl, d2;

getdim(dl, d2);

return 0.5 * dl * d2;

int main {

}

area *p;

rectangle r;

triangle t;

r.setarea{3.3, 4.5)

t.setarea(4.0, 5.0)

Р — & г ;

cout << "Площадь прямоугольника: " << p->getarea() << '\п';

р = fit;

cout << "Площадь треугольника: " << p->getarea() << '\п';

return 0;

3. Конструкторы производных классов.


Базовый класс, производный класс или оба класса вместе могут иметь конструкторы и/или деструкторы. Если у базового и у производного классов имеются конструкторы и деструкторы, то конструкторы выполняются в порядке наследования, а деструкторы—в обратном порядке. Таким образом, конструктор базового класса выполняется раньше конструктора производного класса. Для деструкторов правилен обратный порядок: деструктор производного класса выполняется

раньше деструктора базового класса.

Последовательность выполнения конструкторов и деструкторов достаточно очевидна. Поскольку базовый класс "не знает" о существовании производного, любая инициализация выполняется в нем независимо от производного класса и возможно становится основой для любой инициализации, выполняемой в производном классе. Поэтому инициализация в базовом классе

должна выполняться первой.

С другой стороны, деструктор производного класса должен выполняться раньше деструктора базового класса потому, что базовый класс лежит в основе производного. Если бы деструктор базового класса выполнялся первым, это бы разрушило производный класс. Таким образом, деструктор производного класса должен вызываться до того, как объект прекратит свое

существование.


В этой очень короткой программе показано, в каком порядке выполняются

конструкторы и деструкторы базового и производного классов:

#include

using namespace std;


class base {

public:

base() { cout << "Работа конструктора базового класса \n"; }

~base () { cout "Работа деструктора базового класса \n"; }

class derived: public base {

public:

derived() { cout << "Работа конструктора производного класса\n"; }

-derived () { cout << "Работа деструктора производного класса\n"; }

int main ()

{

derived о;

return 0;


После выполнения программы на экран выводится следующее:


Работа конструктора базового класса

Работа конструктора производного класса

Работа деструктора производного класса

Работа деструктора базового класса

Как видите, конструкторы выполняются в порядке наследования, а деструкторы — в обратном порядке.




Случайные файлы

Файл
129446.rtf
71190.rtf
123961.rtf
27317.rtf
26483-1.rtf




Чтобы не видеть здесь видео-рекламу достаточно стать зарегистрированным пользователем.
Чтобы не видеть никакую рекламу на сайте, нужно стать VIP-пользователем.
Это можно сделать совершенно бесплатно. Читайте подробности тут.