(delphi11最新学习资料) Object Pascal 学习笔记---第12章第4节 (类助手和继承)

12.4.2 类助手和继承

​ 类助手的最大限制是,在任何时候,每个类只能有一个类助手。如果编译器遇到两个类助手,第二个类助手将取代第一个。没有办法将类助手串联起来,也就是说,没有办法用一个类助手再进一步扩展一个已经被其他类助手扩展过的类。

​ 这个问题的部分解决方案来自于这样一个事实:你可以为一个类引入一个类助手,并为该类的子类添加一个进一步的类助手;但你不能直接从另一个类助手继承一个类助手。我并不鼓励使用复杂的类助手结构,因为它们会让你的代码变得错综复杂。

​ 当你要添加到一个库或系统定义的数据结构时,类助手才真正有意义。TGUID 记录就是一个例子,它是一种 Windows 数据结构,使用一个类助手增加了一些通用的功能,从而可以在跨平台的 Object Pascal 中使用:

type
  TGUIDHelper = record helper for TGUID
    class function Create(const B: TBytes): TGUID; overload; static;
    class function Create(const S: string): TGUID; overload; static;
    class function NewGuid: TGUID; static;
    function ToByteArray: TBytes;
    function ToString: string;
  end;

​ 你可能已经注意到 TGUIDHelper 是一个记录助手而不是类助手。是的,记录可以像类一样拥有助手。

12.4.3 使用类助手添加控件枚举

​ Delphi 库中的任何组件都会自动定义一个枚举器,你可以使用它来处理每个拥有的组件,或子组件。例如,在窗体方法中,你可以通过编写以下代码来枚举窗体拥有的组件:

for var AComp in Self do
  ... // 使用 AComp

​ 另一个常用的操作是遍历子控件,其中只包括以窗体为直接父控件的可视化组件(不包括非可视化组件,如 TMainMenu,也不包括由子控件托管的控件,如面板上的按钮)。我们可以使用一种技术来编写更简单的代码循环浏览子控件:为TWinControl 类编写一个类助手,增加新的枚举功能:

type
  TControlsEnumHelper = class helper for TWinControl
    type
      TControlsEnum = class
      private
        NPos: Integer;
        FControl: TWinControl;
      public
        constructor Create(AControl: TWinControl);
        function MoveNext: Boolean;
        function GetCurrent: TControl;
        property Current: TControl read GetCurrent;
      end;
    public
      function GetEnumerator: TControlsEnum;
  end;

注解 该类助手是针对TWinControl 而不是 TControl,原因是只有具有窗口句柄的控件才能成为其他控件的父控件。这基本上排除了图形控件。

​ 这里是类助手的完整代码,包括其唯一的方法和嵌套类 TControlsEnum 的方法:

code{ TControlsEnumHelper }
function TControlsEnumHelper.GetEnumerator: TControlsEnum;
begin
  Result := TControlsEnum.Create(Self);
end;

{ TControlsEnumHelper.TControlsEnum }
constructor TControlsEnumHelper.TControlsEnum.Create(AControl: TWinControl);
begin
  FControl := AControl;
  NPos := -1;
end;

function TControlsEnumHelper.TControlsEnum.GetCurrent: TControl;
begin
  Result := FControl.Controls[NPos];
end;

function TControlsEnumHelper.TControlsEnum.MoveNext: Boolean;
begin
  Inc(NPos);
  Result := NPos < FControl.ControlCount;
end;

图 12.2: 在 Delphi IDE 中用于设计时测试控件枚举助手的窗体

​ 现在,我们创建了一个如图 12.2 所示的窗体,从而可以测试在各种场景中的枚举。第一种情况是我们为其专门编写代码的,即枚举窗体中的子控件:

procedure TControlEnumForm.BtnFormChildClick(Sender: TObject);
begin
  Memo1.Lines.Add('Form Child');
  for var ACtrl in Self do
    Memo1.Lines.Add(ACtrl.Name);
  Memo1.Lines.Add('');
end;

​ 这是Memo控件的操作输出,列出了窗体的子控件,但不包括面板中的其他组件或控件:

Form Child
Memo1
BtnFormChild
Edit1
CheckBox1
RadioButton1
Panel1
BtnFormComps
BtnButtonChild

​ 如果我们枚举所有组件,就可以看到完整的列表。然而,我们在本节开始时编写的代码存在问题,因为我们已经使用新版本的GetNumerator(在类助手中)的方法覆盖了原来的方法,因此我们不能直接访问基类 TComponent 中的枚举器。该类助手是为 TWinControl 定义的,因此我们可以使用一个技巧:我们将我们的对象强制转换为 TComponent,代码将调用标准的、预定义的枚举器:

procedure TControlEnumForm.BtnFormCompsClick(Sender: TObject);
begin
  Memo1.Lines.Add('Form Components');
  for var AComp in TComponent(Self) do
    Memo1.Lines.Add(AComp.Name);
  Memo1.Lines.Add('');
end;

​ 这是输出的结果,列出了比前一个列表更多的组件:

Form Components
Memo1
BtnFormChild
Edit1
CheckBox1
RadioButton1
Panel1
BtnPanelChild
ComboBox1
BtnFormComps
BtnButtonChild
MainMenu1

​ 在 ControlsEnum 示例中,我还添加了用于枚举面板子控件和一个按钮子控件的代码 的子控件的代码(主要是为了测试枚举器在列表为空时能否正常工作 在列表为空时能否正常工作)。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi XE是一种基于Object Pascal编程语言的集成开发环境(IDE),用于开发Windows平台上的应用程序。Delphi编程中的重要概念,它是面向对象编程的基础。 在Delphi XE中,用于封装数据和方法,以创建可重用的代码块。一个可以有属性和方法,属性用于访问和修改对象的数据,而方法用于执行特定的操作。通过使用和对象,可以实现代码的模块化和组织,以提高代码的可维护性和重用性。 在学习Delphi XE的编程时,需要掌握以下几个关键概念: 1. 的定义:使用class关键字来定义一个,可以在中声明属性和方法。 2. 对象的创建:通过使用来创建对象,可以通过实例化的方式来创建对象,并使用对象来调用中的方法和访问属性。 3. 继承与多态:Delphi XE支持继承和多态的特性,允许一个从另一个继承属性和方法,并可以通过多态的方式重写父的方法。 4. 的访问控制:可以使用访问修饰符(如private、protected、public、published)来控制中属性和方法的访问权限。 通过深入学习Delphi XE的编程,可以掌握面向对象编程的核心思想和技巧,能够更好地利用Delphi XE的特性和功能来开发高质量的应用程序。同时,熟练掌握编程还能够提高代码的可读性和可维护性,使代码更易于理解和修改。 综上所述,Delphi XE的学习学习Delphi编程的重要内容。通过深入了解的概念、属性、方法、继承、多态和访问控制等知识点,可以编写出更高效、可扩展和易维护的应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值