Выбрать главу

Пример 1. Обработка неверного ввода данных.

Рассмотрим программу.

var i: integer;

begin

readln(i);

writeln(i);

writeln('Выполнение программы продолжается');

end.

Если при вводе данных произойдет ошибка (например, мы введем не число), то программа завершится с ошибкой (ошибка ввода), и последующие операторы writeln не будут выполнены.

Перехватим исключение в блоке try:

var i: integer;

begin

try

readln(i);

writeln(i);

except

writeln('Ошибка ввода');

end;

writeln('Выполнение программы продолжается');

end.

На этот раз при возникновении ошибки ввода программа не будет завершена, а выполнение будет передано в блок except, после чего выполнение программы продолжится дальше. Таким образом, в последней программе не выполнится лишь оператор writeln(i).

Если в блоке try могут возникнуть различные исключения, то обычно используется вторая форма блока except с несколькими обработчиками исключений.

Пример 2. Обработка различных исключений.

var a,b: integer;

assign(f,'a.txt');

try

readln(a,b);

reset(f);

c:=a div b;

except

on System.DivideByZeroException do

writeln('Целочисленное деление на 0');

on System.IO.IOException do

writeln('Файл отсутствует');

end;

Часто необходимо совмещать обработку исключений и освобождение ресурсов независимо от того, произошло исключение или нет. В этом случае используются вложенные операторы try ... except и try ... finally.

Пример 3. Вложенные операторы try ... except и try ... finally.

assign(f,'a.txt');

try

reset(f);

try

try

c:=a div b;

except

on System.DivideByZeroException do

writeln('Целочисленное деление на 0');

end;

finally

close(f);

end;

except

on System.IO.IOException do

writeln('Файл отсутствует');

end;

Обратим внимание, что в данном примере исключение, связанное c целочисленным делением на 0, обрабатывается в самом внутреннем блоке try, а исключение, связанное с отсутствующим файлом - в самом внешнем. При этом, если файл был открыт, то независимо от возникновения исключения деления на 0 он будет закрыт.

Интерфейсы

Интерфейсы: обзор

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

ИмяИнтерфейса = interface

объявления методов и свойств

end;

Для метода приводится только заголовок, для свойства после возвращаемого типа указываются необходимые модификаторы доступа read и write.

Например:

type

IShape = interface

procedure Draw;

property X: integer read;

property Y: integer read;

end;

ICloneable = interface

function Clone: Object;

end;

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

Класс реализует интерфейс, если он реализует все методы и свойства интерфейса в public-секции. Если класс не реализует хотя бы один метод или свойство интерфейса, возникает ошибка компиляции. Класс может реализовывать также несколько интерфейсов. Список реализуемых интерфейсов указывается в скобках после ключевого слова class (если указано имя предка, то после имени предка).

Например:

type

Point = class(IShape,ICloneable)

private

xx,yy: integer;

public

constructor Create(x,y: integer);

begin

xx := x; yy := y;

end;

procedure Draw; begin end;

property X: integer read xx;

property Y: integer read yy;

function Clone: Object;

begin

Result := new Point(xx,yy);

end;

procedure Print;

begin

write(xx,' ',yy);

end;

end;

Интерфейсы можно наследовать друг от друга:

type

IPosition = interface

property X: integer read;

property Y: integer read;

end;

IDrawable = interface

procedure Draw;

end;

IShape = interface(IPosition,IDrawable)

end;

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

var ip: IShape := new Point(20,30);

ip.Draw;

Point(ip).Print;

Все методы класса, реализующего интерфейс, являются виртуальными без использования ключевых слов virtual или override. В частности, ip.Draw вызовет метод Draw класса Point. Однако, цепочка виртуальности таких методов обрывается. Чтобы продолжить цепочку виртуальности методов, реализующих интерфейс, в подклассах, следует использовать ключевое слово virtual:

type

Point = class(IShape,ICloneable)

...

function Clone: Object; virtual;

begin

Result := new Point(xx,yy);

end;

end;

Для интерфейсов, как и для классов, можно также использовать операции is и as:

if ip is Point then

...

var p: Point := ip as Point;

if p<>nil then

writeln('Преобразование успешно');

Реализация нескольких интерфейсов

Несколько интерфейсов могут содержать одинаковые методы или свойства. При наследовании от таких интерфейсов такие одинаковые методы или свойства сливаются в один: