zoukankan      html  css  js  c++  java
  • 初探Object Pascal的类(八)

    类实例

    讲解了这么多讲了,在此举例一个类的例子是最好不过的了。下面的单元中,包含了一个名叫TAirplane的类,这个类可用于飞机控制器程序。这个类可通过发送有关信息来操作飞机,它可指示飞机起飞、降落,或者改变航程、高度、速度等。先来看看这个单元吧。

    清单 Airplane.pas

    unit Airplane;
    
    interface
    
    uses
      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语句决定发送哪个信息并采取相应行动。其中TakeOffLand过程是不能直接调用的(它们在protected下),但可以通过SendMessage函数调用。

    其中有些过程声明的后面有virtual关键字,此声明表示该函数为虚拟方法(virtual method)

    在该讲的代码示例中有一个Airport程序,此程序能够充当飞行交通控制器,截图如下:

    0059

    此程序首先创建三个TAirplane类数组,然后建立三个TAirPlane类实例。通过选择飞机,可向任何飞机发送有关信息,为这些信息设置参数,然后点击“Execute(执行)”按钮,然后就会调用被选中飞机的SendMessage函数,当消息发送时,会得到飞机的返回信息,此信息显示在Memo控件中,运行此程序,感受下此程序是如何工作的。

    以上代码均在Delphi7中测试通过,实例代码下载:Airplane飞行类的实现.rar

  • 相关阅读:
    Ubuntu安装配置samba
    AFNetworking 和 ASIHTTPRequest
    github代码托管
    Java使用poi包读取Excel文档
    Eclipse-设置保存时自动给变量加final
    Eclipse-设置格式化代码时不格式化注释
    Map的内容按字母顺序排序
    Mysql--mysqldump命令 备份数据库
    Mysql--alter命令
    Java IO 文件
  • 原文地址:https://www.cnblogs.com/pchmonster/p/2307367.html
Copyright © 2011-2022 走看看