Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
3-6-9-12....doc
Скачиваний:
1
Добавлен:
04.08.2019
Размер:
102.91 Кб
Скачать

3 БИЛЕТ

Полиморфизм основывается на возможности включения в данные объекта информации о методах их обработки (в виде указателей на функции). Будучи доступным в некоторой точке программы, даже при отсутствии полной информации о его типе, он всегда может корректно вызвать свойственные ему методы.

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

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

При позднем связывании адреса определяются динамически во время выполнения программы, а не статически во время компиляции, как в традиционных компилируемых языках, в которых применяется раннее связывание. Сам процесс связывания заключается в замене виртуальных функций на адреса памяти.

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

6 Билет

Все присущие объекту характеристики в терминах ООП называют полями. По сути, это принадлежащие объекту переменные определённого типа, в которые записываются значения, отражающие состояние объекта. Для управления объектом предназначены его методы. В первую очередь методы воздействуют на поля объекта. Если методы объекта возвращают какое-нибудь значение, то они реализуются в виде функций, в противном случае метод представляется процедурой.

Объект не может возникнуть из воздуха, среда программирования каким-то образом должна быть проинформирована о его характеристиках. Поэтому предварительно программист описывает объект; такое описание называется классом. Класс - это чертёж будущего объекта, в котором учитываются не только его конструктивные элементы (поля), но и определяются способы управления этими элементами - методы класса.

Определение класса начинается с ключевого слова type глобального блока, за которым следуют имя класса, его поля и методы. Завершается описание директивой end. В объявление класса могут входить другие классы; таким образом можно создавать сложные составные объекты. По форме объявления классы похожи на обычные записи, но помимо полей данных могут содержать объявления пользовательских процедур и функций (методы). Пример:

type TPeople = class

Name: string;

Family: string;

procedure GetName;

procedure GetFamily;

end;

Класс содержит поля (Name, Family) и методы (GetName, GetFamily). Заголовки методов, всегда следующие за списком полей, играют роль упреждающих описаний. Программный код методов пишется отдельно от определения класса и будет приведён позже.

Чтобы от описания класса перейти к объекту, следует выполнить следующее объявление в секции var:

var People: TPeople;

При работе с обычными типами данных этого объявления было бы достаточно для получения экземпляра типа. Однако объекты среды Delphi являются динамическими данными, то есть распределяются в динамической памяти. Поэтому переменная People - это просто ссылка на экземпляр (объект в памяти), которого физически ещё не существует. Чтобы сконструировать объект (выделить память для экземпляра) класса TPeople и связать с ним переменную People, нужно в тексте программы поместить следующий оператор:

People := TPeople.Create; //Выделение памяти под объект

Create - это так называемый конструктор объекта; он всегда присутствует в классе и служит для создания и инициализации экземпляров. При создании объекта в памяти выделяется место только для его полей. Методы, как и обычные процедуры и функции, помещаются в область кода программы; они умеют работать с любыми экземплярами своего класса и не дублируются в памяти. После создания объект можно использовать в программе: получать и устанавливать значения его полей, вызывать его методы. Доступ к полям и методам объекта происходит с помощью уточнённых имён, например:

People.GetName;

People.GetFamily;

Кроме того, как и при работе с записями, допустимо использование оператора with, например:

with People do

GetFamily;

GetName;

Если объект становится ненужным, он должен быть удалён вызова специального метода Destroy, например:

People.Destroy; //Освобождение памяти, занимаемой объектом

Destroy - это так называемый деструктор объекта; он присутствует в классе наряду с конструктором и служит для удаления объекта из динамической памяти. После вызова деструктора переменная People становится несвязанной и не должна использоваться для доступа к полям и методам уже несуществующего объекта. Чтобы отличать в программе связанные объектные переменные от несвязанных, последнее следует инициализировать значением nil. Пример:

People := nil;

if People <> nil then People.Destroy;

Вызов деструктора для несуществующих объектов недопустим и при выполнении программы приведёт к ошибке. Чтобы избавить программистов от лишних ошибок, в объекты ввели предоставленный метод Free, который следует вызвать вместо деструктора. Метод Free сам вызывает деструктор Destroy, но только в том случае, если значение объектной переменной не равно nil. Поэтому последнюю строчку в приведённом выше примере можно переписать следующим образом:

People.Free;

После уничтожения объекта переменная People сохраняет своё значение, продолжая ссылаться на место в памяти, где объекта уже нет. Если эту переменную предполагается ещё использовать, то желательно присвоить ей значение nil, чтобы программа могла проверить, существует объект или нет. Таким образом, наиболее правильная последовательность действий при уничтожении объекта должна быть следующая:

People. Free;

People := nil;

С помощью стандартной процедуры FreeAndNil это можно сделать проще и элегантнее:

FreeAndNil(People); //Эквивалентно: People. Free; People := nil;

Значение одной объектной переменной можно присвоить другой. При этом объект не копируется в памяти, а вторая переменая просто связывается с тем же объектом, что и первая:

var People1, People2: TPeople;

begin

People1 := TPeople.Create;

People1 := People2;

People. Free;

end;

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