【www.tuzhexing.com--教育考试】
12.3.5 自定义异常类的应用
利用Delphi的异常类机制我们可以定义自己的异常类来处理程序执行中的异常情况。同标准异常不同的是:这种异常情况并不是相对于系统的正常运行,而是应用程序的预设定状态。比如输入一个非法的口令、输入数据值超出设定范围、计算结果偏离预计值等等。
使用自定义异常需要:
1.自己定义一个异常对象类;
2.自己引发一个异常。
12.3.5.1 定义异常对象类
异常是对象,所以定义一类新的异常同定义一个新的对象类型并无太大区别。由于缺省异常处理只处理从Exception或Exception子类继承的对象,因而自定义异常类应该作为Exception或其它标准异常类的子类。这样,假如在一个模块中引发了一个新定义的异常,而这个模块并没有包含对应的异常响应,则缺省异常处理机制将响应该异常,显示一个包含异常类名称和错误信息的消息框。
下面是一个异常类的定义:
type
EMyException = Class(Exception) ;
12.3.5.2 自引发异常
引发一个异常,调用保留字raise,后边跟一个异常类的实例。
假如定义:
type
EPasswordInvalid = Class(Exception);
则在程序中如下的语句将引发一个EPasswordInvalid异常:
If Password <> CorrectPassword then
raise EPasswordInvalid.Create("Incorrect Password entered");
异常产生时把System库单元中定义的变量ErrorAddr的值置为应用程序产生异常处的地址。在你的异常处理过程中可以引用ErrorAddr的值。
在自己引发一个异常时,同样可以为ErrorAddr分配一个值。
为异常分配一个错误地址需要使用保留字at,使用格式如下:
raise EInstance at Address_Expession;
12.3.5.3 自定义异常的应用举例
下面我们给出一个利用自定义异常编程的完整实例。
两个标签框(Label1、Label2)标示对应编辑框的功能。编辑框PassWord和InputEdit用于输入口令和数字。程序启动时Label2、InputEdit不可见。当在PassWord中输入正确的口令时,Label2、InputBox出现在屏幕上。此时Label1、PassWord隐藏。
设计时,令Label2、InputEdit的Visible属性为False。通过设置PassWord的PassWordChar可以确定输入口令时回显在屏幕上的字符。
自定义异常EInvalidPassWord和EInvalidInput分别用于表示输入的口令非法和数字非法。它们都是自定义异常EInValidation的子类。而EInValidation直接从Exception异常类派生。
下面是三个异常类的定义。
type
EInValidation = class(Exception)
public
ErrorCode: Integer;
constructor Create(Const Msg: String;ErrorNum: Integer);
end;
EInvalidPassWord = class(EInValidation)
public
constructor Create;
end;
EInvalidInput = class(EInValidation)
public
constructor Create(ErrorNum: Integer);
end;
EInValidation增加了一个公有成员ErrorCode来保存错误代码。错误代码的增加提供了很大的编程灵活性。对于异常类,可以根据错误代码提供不同的错误信息;对于使用者可以通过截取错误代码,在try…except模块之外来处理异常。
从以上定义可以发现:EInvalidPassWord和EInvalidInput的构造函数参数表中没有表示错误信息的参数。
。事实上,它们保存在构造函数内部。下面是三个自定义异常类构造函数的实现代码。
constructor EInValidation.Create(Const Msg: String; ErrorNum: Integer);
begin
inherited Create(Msg);
ErrorCode := ErrorNum;
end;
constructor EInValidPassWord.Create;
begin
inherited Create("Invalid Password Entered",0);
end;
constructor EInValidInput.Create(ErrorNum: Integer);
var
Msg: String;
begin
case ErrorNum of
1:
Msg := "Can not convert String to Number";
2:
Msg := "Number is out of Range";
else
Msg := "Input is Invalid";
end;
inherited Create(Msg,ErrorNum);
end;
对于EInvalidInput,ErrorCode=1表示输入的不是纯数字序列,而ErrorCode=2表示输入数值越界。
口令检查是用户在PassWord中输入口令并按下回车键后开始的。实现代码在PassWord的OnKeyPress事件处理过程中:
procedure TForm1.PassWordKeyPress(Sender: TObject; var Key: Char);
const
CurrentPassWord = "Delphi";
begin
if Key = #13 then
begin
try
if PassWord.text <> CurrentPassWord then
raise EInvalidPassWord.Create;
Label2.Visible := True;
InputEdit.Visible := True;
InputEdit.SetFocus;
PassWord.Visible := False;
Label1.Visible := False;
except
on EInvalidPassWord do
begin
PassWord.text := "";
raise;
end;
end;
Key:=#0;
end;
end;
同样,在InputEdit的OnKryPress事件处理过程中实现了输入数字的合法性检查:
procedure TForm1.InputEditKeyPress(Sender: TObject; var Key: Char);
var
Res: Real;
Code: Integer;
begin
if Key = #13 then
begin
try
val(InputEdit.text,Res,Code);
if Code <> 0 then
raise EInValidInput.create(1);
if (Res > 1) or (Res < 0) then
raise EInValidInput.create(2);
MessageDlg("Correct Input", mtInformation,[mbOk], 0);
Key := #0;
except
on E:EInValidInput do
begin
InputEdit.text := "";
Messag
eDlg(E.Message, mtWarning,[mbOk], 0);
end;
end;
end;
end;
由于异常响应后即被清除,所以要显示异常信息,需要另外的手段。在以上两段程序中我们采用了两种不同的方法:在口令合法性检查中,利用异常重引发由系统进行缺省响应;在输入数字合法性检查中,通过异常实例来获取异常信息并由自己来显示它。
以上所举的是一个非常简单的例子,但从中已可以发现:使用自定义异常编程,为程序设计带来了很大的灵活性。