16.1.5. Создание собственного класса
Программист может создать собственный класс обработки исключений, объявив его потомком Exception или любого другого стандартного класса (этим другим чаще всего бывает класс EAbort). Объявление нестандартного класса имеет смысл только тогда, когда вам необходимо научить программу распознавать некорректные наборы данных и соответствующим образом на них реагировать.
Пусть, например, в программе используется цикл ввода целочисленных значений из текстового файла, их проверки и преобразования. Проверка заключается в простом контроле неотрицательности очередного числа после ввода и его положительности после преобразования. Перед проверкой необходимо получить строку из файла (здесь может возникнуть ошибка EinOutError) и преобразовать ее в целую величину (здесь возможна ошибка EConvertError); после проверки осуществляется обработка величины, в процессе которой может возникнуть ошибка EIntError.
Создадим новый класс EIntCheckError и будем возбуждать исключение этого класса при обнаружении ошибки в данных:
type
EIntCheckError = class(EAbort)
end;
var
F: TextFile;
S: String;
k: Integer;
begin
try
// Готовимся к работе: открываем файл AssignFile(F, FileName);
Reset(F); // Здесь возможна ошибка EinOutError // Цикл ввода-контроля-преобразования while not EOF(F) do begin
// Вводим символы очередного числа
ReadLn(F,S);// Здесь возможна ошибка EinOutError
// Преобразуем символы в число
k := StrToInt(S); // Здесь возможна ошибка EConvertError
// Проверяем число
if k < 0 then
raise EIntCheckError.Create("Отрицательное число');
// Преобразуем число
..... // Здесь возможна ошибка EIntError
// Вновь проверяем число
if k <= 0 then
raise EIntCheckError.Create('He положительное число');
end;
except
on E: EIntCheckError do
ShowMessage(E.Message) ;
on EInOutError do
ShowMessage('Некорректная файловая операция');
on EConvertError do
ShowMessage('Ошибка в записи числа');
on EIntError do
ShowMessage('Ошибка преобразования');
end;
end;
В этом примере создается класс EIntCheckError, который ничем, кроме названия, не отличается от своего родителя EAbort. В реальной программе потомок обычно расширяет набор полей (свойств) своего родителя или перекрывает его методы; приведенный пример лишь иллюстрирует, что делать это необязательно. При неудачной проверке операторами
raise EIntCheckError.Create('Отрицательное число') ;
и
raise EIntCheckError.Create('Ошибка преобразования');
возбуждается исключение нового класса. При этом с помощью унаследованного конструктора create создается новый безымянный объект, а строковый параметр обращения к конструктору запоминается в поле FMessage и становится доступен с помощью свойства Message объекта. Обработчик исключения EIntCheckError именует объект идентификатором e и с помощью стандартной процедуры ShowMessage показывает его в небольшом окне на экране.
Пример наглядно показывает выгоды использования исключений. В принципе весь этот фрагмент можно было бы написать с многочисленными проверками if... then, но в этом случае логика программы стала бы запутанной, а сама программа - сложной в отладке.