Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
65
Добавлен:
10.12.2013
Размер:
166.21 Кб
Скачать

ВОПР 1

Классы

Объявление класса

Класс — это тип данных, определяемый пользователем.

Класс должен быть объявлен до того, как будет объявлена хотя бы одна пере­менная этого класса. Т.е. класс не может объявляться внутри объявления перемен­ной.

Синтаксис объявления класса следующий:

Туре <имя класса> = Class (<имя класса — родителя>) public {доступно всем}

<поля, методы, свойства, события> published {видны в Инспекторе Объекта и изменяемы} <поля, свойства>

protected {доступ только потомкам}

<поля, методы, свойства, события>

private (только в модуле}

<поля, методы, свойства, события>

end;

Имя класса может быть любым допустимым идентификатором. Но принято идентификаторы большинства классов начинать с символа «Т». Имя класса — ро­дителя может не указываться. Тогда предполагается, что данный класс является непосредственным наследником TObject — наиболее общего из предопределенных классов.

type TMyClass = class end;

И

type TMyClass = class (TObject)

end;

Класс наследует поля, методы, свойства, события от своих предков и может отменять какие-то из этих элементов класса или вводить новые. Доступ к объявля­емым элементам класса определяется тем, в каком разделе они объявлены.

Раздел public (открытый) предназначен для объявлений, которые доступны для внешнего использования. Это открытый интерфейс класса.

Раздел published (публикуемый) содержит открытые свойства, которые появляются в процессе про­ектирования на странице свойств Инспектора Объектов и которые, следовательно, пользователь может устанавливать в процессе проектирования.

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

Раздел protected (защищенный) содержит объявления, до­ступные только для потомков объявляемого класса.

Объявления полей выглядят так же, как объявления переменных или объяв­ления полей в записях:

<имя поля>: <тип>;

Объявления методов в простейшем случае также не отличаются от обычных объявлений процедур и функций.

Свойства

Доступ к полям данных, как правило, должен осу­ществляться только через свойства, включающие методы чтения и записи полей. Поэтому поля целесообразно объявлять в разделе private — закрытом разделе класса. В редких случаях их можно помещать в protected — защищенном разделе класса, чтобы возможные потомки данного класса имели к ним доступ. Традици­онно идентификаторы полей совпадают с именами соответствующих свойств, но с добавлением в качестве префикса символа 'F'.

Свойство объявляется оператором вида:

property <имя свойства>:<тип> read <имя поля или метода чтения> write <имя поля или метода записи> <директивы запоминания;

Если в разделах read или write этого объявления записано имя поля, значит предполагается прямое чтение или запись данных.

Если в разделе read записано имя метода чтения, то чтение будет осуществля­ться только функцией с этим именем. Функция чтения — это функция без пара­метра, возвращающее значение того типа, который объявлен для свойства. Имя функции чтения принято начинать с префикса Get, после которого следует имя свойства.

Если в разделе write записано имя метода записи, то запись будет осуществля­ться только процедурой с этим именем. Процедура записи — это процедура с од­ним параметром того типа, который объявлен для свойства. Имя процедуры запи­си принято начинать с префикса Set, после которого следует имя свойства.

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

Приведем пример. Пусть требуется объявить класс с именем MyC!ass, насле­дующий непосредственно TObject и имеющий свойство целого типа с именем А. Тогда объявление этого класса может иметь вид:

type

MyClass = class(TObject} private

FA: integer; protected

procedure SetA(Value: integer); {Процедура записи} published

property A:integer read FA write SetA default true; end;

Здесь вводится закрытое поле FA, объявляется защищенная функция SetA, используемая для записи значения этого поля, и вводится опубликованное свойст­во А, оперирующее этим полем. В объявлении свойства после ключевого слова read записано просто имя поля. Это означает, что функция чтения отсутствует и пользователь может читать непосредственно значение поля. После ключевого сло­ва write следует ссылка на функцию записи SetA, с помощью которой будут запи­сываться в поле А новые значения. В этой функции можно предусмотреть какие-то проверки допустимости вводимого значения А.

Вопр 2 Наследование

Любой класс жожет быть порожден от другого класса. Для этого при его объявлении указывается имя класса-родителя:

TChildClass = class(TParentClass)

Порожденный класс автоматически наследует поля, методы и свойства своего родите­ля и_может добавлять их новыми. Таким образом, принцип наследования обеспечивает поэтапное создание сложных классов и разработку собственных библиотек классов. Все классы Object Pascal порождены от единственного родителя - класса TObject. Этот класс не имеет полей и свойств, но включает в себя методы самого общего.на­значения, обеспечивающие весь жизненный цикл любых объектов - от их создания до уничтожения. Программист не может создать класс, который не был бы дочерним классом TObject. Следующие два объявления идентичны:

TaClass = class (TObject) TaClass = class

Принцип наследования приводит к созданию ветвящегося дерева классов, посте­пенно разрастающегося при перемещении от TObject к его потомкам. Каждый пото­мок дополняет возможности своего родителя новыми и передает их своим потомкам.

Методы и их наследование, полиморфизм

При описании нового класса можно добавлять новые методы и свойства, остав­ляя методы и свойства родителей, а можно родительские методы и свойства пере­определить или перегрузить.

Имеется четыре вида методов: статические, виртуальные, динамические и абстрактные.

По умолчанию все методы статические. Если в классе — наследнике переоп­ределить такой метод (ввести новый метод с тем же именем), то для объектов этого класса новый метод отменит родительский. Если обращаться к объекту этого клас­са, то вызываться будет новый метод. Но если обратиться к объекту как к объекту родительского класса, то вызываться будет метод родителя.

Виртуальные и динамические методы не связаны с другими методами с тем же именем в классах — наследниках. Если в классах — наследниках эти методы перегружены, то при обращении к такому методу во время выполнения будет вы­зываться тот из методов с одинаковыми именами, который соответствует классу объекта, указанному при вызове. Например, если имеется базовый класс графиче­ских объектов TShape и ряд наследующих ему классов различных геометрических фигур, и если в каждом из этих классов определен свой виртуальный метод Draw, рисующий эту фигуру, то можно написать в программе:

var ShapeArray: array[1..10] of TShape;

for i:=l to 10 do ShapeArray[i].Draw;

В этом коде в массив ShapeArray могут помещаться объекты разных классов, наследующих TShape. В цикле for обращение к объектам производится как к объ­ектам базового для них типа TShape. В этом случае для каждого объекта будет вы­зываться виртуальный метод Draw именно этого объекта. Такой подход, облегчаю­щий работу с множеством родственных объектов, называется полиморфизмом.

При объявлении в классе виртуальных и динамических методов после точки с запятой, завершающей объявление метода, добавляются ключевые слова virtual или dynamic. Например:

type

TShape = class

procedure Draw; virtual;

end;

Чтобы перегрузить в классе — наследнике виртуальный метод, надо после его объявления поставит ключевое слово override. Например:

type

TRectangle = class(TShape)

procedure Draw; override;

end;

TEllipse = class (TShape)

procedure Draw; override; end;

Если в каком-то базовом классе метод был объявлен как виртуальный, то он остается виртуальным во всех классах — наследниках (в частности, и в наследни­ках классов наследников). Однако, обычно для облегчения понимания кодов перегруженные методы принято повторно объявлять виртуальными, чтобы была ясна их суть для тех, кто будет строить наследников данного класса. Например:

TEllipse = class (TShape)

procedure Draw; override; virtual;

end;

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

Абстрактный метод — это виртуальный или динамический метод, реализа­ция которого не определена в том классе, в котором он объявлен. Предполагается, что этот метод будет перегружен в классах — наследниках. Только в тех классах, в которых он перегружен, его и можно вызывать.

Объявляется абстрактный метод с помощью ключевого слова abstract после слова virtual или dynamic. Например:

procedure DoSomething; virtual; abstract;

При реализации метода, переопределенного любым способом в классе — на­следнике, можно вызывать метод класса — родителя. Для этого перед именем ме­тода при его вызове записывается ключевое слово inherited. Например, оператор

inherited Create (...);

вызывает метод Create родителя.

Если записать слово inherited и после него не писать имя вызываемого метода, то будет вызываться наследуемый метод, совпадающий по имени с именем того ме­тода, из которого он вызывается. Например, если в переопределяемом конструкто­ре встречается оператор

inherited; то будет вызван конструктор родительского класса.

ВОПР 3

Класс Exceptionявляется прямым потомком базового класса TObject. Вместе со своими потомками он предназначен для обработки исключительных ситуаций (исключений), возникающих при некорректных действиях программы: например, в случае деления на ноль, при попытке открыть несуществующий файл, при выходе за пределы выделен­ной области динамической памяти и т, п.

Защищенные блоки

Для обработки исключений в Object Pascal предусмотрен механизм защищенного блока:

Try try

<операторы> <операторы> except finally

<обработчики исключений> <операторы>

elseend;

<операторы> end;

Защищенный блок начинается зарезервированным словом try (попытаться [выполнить]) и завершается словом end. Существует два типа защищенных блоков -except (исключить) и finally (в завершение), отличающихся способом обработки исключения.

В блоке except порядок выполнения операторов таков: сначала выпол­няются операторы секции try.. .except; если операторы выполнены без возникновения исключительной ситуации, работа защищенного блока на этом прекращается и управление получает оператор, стоящий за end; если при выполнении части try возникло исключение, управление получает соответствующий обработчик в секции ex­cept, а если таковой не найден - первый из операторов, стоящих за словом else.

В блоке finally операторы в секции finally...end получают управление всегда, независимо от того, возникло исключение в секции try.. .finally или нет. Если исключение возникло, все операторы в секции try.. .finally, стоящие за «виновником» исключения, пропускаются и управление получает первый оператор секции finally.. .end. Если исключения не было, этот оператор получает управле­ние после выполнения последнего оператора секции try... finally.

Обработчики исключений в блоке except имеют такой синтаксис:

on <класс исключения> do <оператор>;

Здесь on, do - зарезервированные слова; <класс исключения> - класс обработки исключения; <оператор> - любой оператор Object Pascal, кроме оператора передачи управления goto на метку вне блока except.

Обратите внимание: имя класса служит своеобразным ключом выбора, а собствен­но обработка осуществляется оператором, стоящим за do (этот оператор может быть составным, так что обработка исключения может занимать произвольное количество операторов Object Pascal).

Поиск нужного обработчика осуществляется с начала списка вниз до тех пор, пока не встретится класс, способный обрабатывать исключение данного типа. Если подхо­дящего класса не обнаружено, управление передается операторам, стоящим за словом else, а если таковых нет (часть else <операторы> может опускаться), выполняется умалчиваемая обработка исключения.

Защищенные блоки могут вкладываться друг в друга на неограниченную глубину, т. к. везде, где в предыдущих описаниях использовались <операторы> или <оператор>, могут использоваться любые операторы Object Pascal, в том числе и try...except или try...finally.

Класс Exception является родительским классом для всех классов-исключений. Этот класс объявляется в модуле SysUtils.

ВОПР 4

Соседние файлы в папке Экзамен