类实例
讲解了这么多讲了,在此举例一个类的例子是最好不过的了。下面的单元中,包含了一个名叫TAirplane的类,这个类可用于飞机控制器程序。这个类可通过发送有关信息来操作飞机,它可指示飞机起飞、降落,或者改变航程、高度、速度等。先来看看这个单元吧。
清单 Airplane.pas
unit Airplane;interfaceuses SysUtils;const { 飞机类型} Airliner = 0; { 班机} Commuter = 1; { 通勤机} PrivateCraft = 2; { 私人机} { 状态常量.} TakingOff = 0; { 起飞} Cruising = 1; { 巡航} Landing = 2; { 着陆} OnRamp = 3; { 停机坪} { 消息常量.} MsgChange = 0; { 改变} MsgTakeOff = 1; { 起飞} MsgLand = 2; { 着陆} MsgReport = 3; { 报告}type TAirplane = class private Name: string; { 飞机名称} Speed: Integer; { 飞行速度} Altitude: Integer; { 飞行高度} Heading: Integer; { 飞行航向} Status: Integer; { 飞行状况} Kind: Integer; { } Ceiling: Integer; { 飞行升限} protected procedure TakeOff(Dir: Integer); virtual; { 起飞} procedure Land; virtual; { 着陆} public constructor Create(AName: string; AKind: Integer = Airliner); function SendMessage(Msg: Integer; var Response: string; { 发送消息} Spd: Integer; Dir: Integer; Alt: Integer): Boolean; function GetStatus(var StatusString: string): Integer; overload; virtual; function GetStatus: Integer; overload; function GetSpeed: Integer; function GetHeading: Integer; function GetAltitude: Integer; function GetName: string; end;implementation{ TAirplane }constructor TAirplane.Create(AName: string; AKind: Integer);begin { 初始化过程,设置飞机名称、类型和升限} inherited Create; Name := AName; Kind := AKind; Status := OnRamp; case Kind of Airliner: Ceiling := 35000; Commuter: Ceiling := 20000; PrivateCraft: Ceiling := 8000; end;end;function TAirplane.GetAltitude: Integer;begin Result := Altitude;end;function TAirplane.GetHeading: Integer;begin Result := Heading;end;function TAirplane.GetName: string;begin Result := Name;end;function TAirplane.GetSpeed: Integer;begin Result := Speed;end;function TAirplane.GetStatus: Integer;begin Result := Status;end;function TAirplane.GetStatus(var StatusString: string): Integer;begin StatusString := Format('%s, Altitude(高度): %d, Heading(航向): %d, ' + 'Speed(速度): %d', [Name, Altitude, Heading, Speed]); { 返回 名称,飞行高度,航向,速度 信息} Result := Status;end;procedure TAirplane.Land;begin { 飞机着陆,设置速度为0,航向为0,高度为0,状态为停机坪} Speed := 0; Heading := 0; Altitude := 0; Status := OnRamp;end;function TAirplane.SendMessage(Msg: Integer; var Response: string; Spd, Dir, Alt: Integer): Boolean;begin Result := True; { 根据Msg消息的类型,响应不同的命令} case Msg of MsgTakeOff: { 起飞命令} { 如果已经在飞行,就不能响应起飞命令} if Status <> OnRamp then begin Response := Name + ':I''m already in the air!(已经在飞行中)'; Result := False; end else TakeOff(Dir); MsgChange: { 改变速度、航向、高度的命令} begin { 飞行速度不能大于500,航向不能超过360度,高度不能低于100,} if Spd > 500 then Response := 'Command Error(错误指令): ' + 'Speed cannot be more than 500.(速度不能超过500)'; if Dir > 360 then Response := 'Command Error(错误指令): ' + 'Heading cannot be over 360 degress.(航向不能超过360度)'; if Alt < 100 then Response := Name + ':I''d crash!(飞行高度太低,将要坠毁!)'; if Alt > Ceiling then Response := Name + ':I can''t go that high.(飞行高度超过该飞行升限)'; if (Spd = 0) and (Dir = 0) and (Alt = 0) then Response := Name + ':Huh?(嗯?无法理解的指令)'; if Response <> '' then begin Result := False; Exit; end; { 如果飞机不在停机坪,则响应指令,改变状态} if Status = OnRamp then begin Response := Name + ':I''m on the ground.(我已经在停机坪)'; Result := False; end else begin Speed := Spd; Heading := Dir; Altitude := Alt; Status := Cruising; end; end; MsgLand: { 着陆指令} { 如果已经在停机坪,则不响应该命令} if Status = OnRamp then begin Response := Name + ':I''m already on the ground.(我已经在停机坪)'; Result := False; end else Land; MsgReport: { 返回当前飞行状况} begin GetStatus(Response); Exit; end; end; { 如果命令得到执行,返回收到} if Result then Response := Name + ':Roger.(收到)';end;procedure TAirplane.TakeOff(Dir: Integer);begin { 设置航向起飞} Heading := Dir; Status := TakingOff;end;end.
分析
首先看看interface段的类声明,注意TAirplane类有一个重载函数叫GetStatus。当用一个字符串参数调用GetStatus时,在返回一个状态字符串的同时还会将Status字段返回。当不用参数调用时,只是返回Status字段值。其中存取私有字段的唯一方式是通过公用方法。例如只有通过发送有关信息才能改变速度、高度和飞行航向。
现在在关注下implementation段中的TAirplane类定义,构造函数执行一些初始化工作,SendMessage函数做了主要工作,Case语句决定发送哪个信息并采取相应行动。其中TakeOff和Land过程是不能直接调用的(它们在protected下),但可以通过SendMessage函数调用。
其中有些过程声明的后面有virtual关键字,此声明表示该函数为虚拟方法(virtual method)。
在该讲的代码示例中有一个Airport程序,此程序能够充当飞行交通控制器,截图如下:
此程序首先创建三个TAirplane类数组,然后建立三个TAirPlane类实例。通过选择飞机,可向任何飞机发送有关信息,为这些信息设置参数,然后点击“Execute(执行)”按钮,然后就会调用被选中飞机的SendMessage函数,当消息发送时,会得到飞机的返回信息,此信息显示在Memo控件中,运行此程序,感受下此程序是如何工作的。
以上代码均在Delphi7中测试通过,实例代码下载: