http://blog.csdn.net/blue_morning/article/details/8815609

Delphi 类的类 class of 用法

 
这个概念本来在一个关于Delphi RTTI 介绍的文档中已经说得很清楚了。但没有任何关于实际使用的介绍,在我明白了这个概念和如何使用后决定写一个使用说明以方便大家使用。

类的类在什么时候使用:
知道父类但需要创建具体的子类时(你不知道子类会是什么)

例如:
一个Delphi Exe程序中项目文件的Application.CreateForm,跟踪下源代码就能明白,Delphi实现了在根本不知道我们会从TForm派生出什么类的情况下,实现了对这个类的创建。

关键:
  TComponentClass = class of TComponent;

  procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);
  begin
    Instance := TComponent(InstanceClass.NewInstance);
    Instance.Create(Self);

    ...

end;

关键的代码就是加粗的这两句和类的类声明

本质:

类的类在声明时,说明相应的类及子类会被编译器附加额外的信息(RTTI),以让系统可以找到具体子类的Create和NewInstance地址。应该就是这样。

代价:

额外的RTTI信息会使我们的类占用额外的内存,这是便利的代价。

简单的问题复杂的说明

本来问题已经说明,但还是存在一个问题:我们的代码中什么地方需要使用class of ?我发现这个问题说明起来很复杂,我举个我人个开发使用的例子。在做数据库程序开发时:我先定义一个TTableSet对象,其功能类似DataModule。用于放置TExportTable,TExportTable类其功能类似TDataSet。我定义了它的增、删、改、查等基本操作。TTableSet对象有一个Add方法,大概代码如下:

procedure TTableSet.Add(const AExoprtObjectInfo: record)
var
  ExprotTable: TExportTable;
begin
  ExprotTable := TExportTable.Create(nil)
  根据AExoprtObjectInfo的数据内容具体化ExportTable对象以方便复用代码
end;

然后,在具体的业务功能(例如入库单管理)中需要从TExportTable继承一个入库单类
TInStorageBill = class(TExportTable)
   一些具体的类属性和方法
  覆盖TExportTable的Create方法以创建相应的资源
end;

废话了那么多,问题才终于出现了:“我怎么才能在TTableSet.Add()方法中创建TInStorageBill对象?”或换而言之:“我怎么在在知道父类的情况下创建其不确定的子类?”。 而你们都知道答案了。

欢迎使用 class of

Delphi 类的类 class of 用法的更多相关文章

  1. Delphi中线程类TThread实现多线程编程1---构造、析构……

    参考:http://www.cnblogs.com/rogee/archive/2010/09/20/1832053.html Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大 ...

  2. Delphi中TStringList类常用属性方法详解

    TStrings是一个抽象类,在实际开发中,是除了基本类型外,应用得最多的. 常规的用法大家都知道,现在来讨论它的一些高级的用法. 先把要讨论的几个属性列出来: 1.CommaText 2.Delim ...

  3. 转发 Delphi中线程类TThread 实现多线程编程

    Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchr ...

  4. 转:学习笔记: Delphi之线程类TThread

    学习笔记: Delphi之线程类TThread - 5207 - 博客园http://www.cnblogs.com/5207/p/4426074.html 新的公司接手的第一份工作就是一个多线程计算 ...

  5. 学习笔记: Delphi之线程类TThread

    新的公司接手的第一份工作就是一个多线程计算的小系统.也幸亏最近对线程有了一些学习,这次一接手就起到了作用.但是在实际的开发过程中还是发现了许多的问题,比如挂起与终止的概念都没有弄明白,导致浪费许多的时 ...

  6. 谈谈Delphi中的类和对象3---抽象类和它的实例

    四.抽象类和它的实例 Delphi中有一个类称为是抽象类,你不能天真的直接为它创建一个实例,如 var StrLst: TString; begin StrLst:= TString.Create; ...

  7. Delphi之TComponent类

    TComponent类 TComponent类直接由TPersistent派生.TComponent的独特特征是它的属性能够在设计期间通过ObjectInspector来控制,能够拥有其他组件.非可视 ...

  8. Delphi Class of 类引用

    Delphi Class of 类引用也就是类的类型,也可说是指向类的指针 Type TControlCls = Class of TControl;function CreateComponent( ...

  9. C#中IPAddress类/Dns类/IPHostEntry类/IPEndPoint用法简介

    C#中IPAddress类/Dns类/IPHostEntry类/IPEndPoint用法简介 IP是一种普遍应用于因特网.允许不同主机能够相互找到对方的寻址协议.IP地址由4个十进制的数字号码所组成, ...

随机推荐

  1. mysql数据库的快捷键

    mysql数据库快捷键 ctrl+q 打开查询窗口 ctrl+/ 注释sql语句 ctrl+shift +/ 解除注释 ctrl+r 运行查询窗口的sql语句 ctrl+shift+r 只运行选中的s ...

  2. mongoexport导出csv中文乱码

    在用mongoexport导出csv文件时,发现数据库中的中文在excel中都显示为乱码,用notepad打开则正常. 解决办法: 在notepad中,将编码格式改为UTF-8,保存,再用excel打 ...

  3. 转:VMWare服务器虚拟化--转自CSDN

    http://blog.csdn.net/kkfloat/article/category/1249845/3

  4. linux usb枚举过程分析之守护进程及其唤醒【转】

    转自:http://blog.csdn.net/xuelin273/article/details/38646765 usb热插拔,即usb设备可以实现即插即用,像U盘一样,插到电脑里就可以用,不用时 ...

  5. Casperjs循环执行(重复执行不退出)

    var casper = require('casper').create({ // pageSettings: { // loadImages: true, // loadPlugins: fals ...

  6. elasticsearch常见异常及解决办法

    报错信息:Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000085330000, 20602552 ...

  7. js async await 终极异步解决方案

    既然有了promise 为什么还要有async await ? 当然是promise 也不是完美的异步解决方案,而 async await 的写法看起来更加简单且容易理解. 回顾 Promise Pr ...

  8. 如何将同一个APP中的不同activity在Recent(最近任务)中显示?

    需求描述 在应用Application1中存在A.B两个activity,当在应用启动了A.B activity,点击Recent键,如何让A.B两个activity都显示在Recent界面(最近任务 ...

  9. 使用 Gradle 对应用进行个性化定制

    啥也不说了,直接进入主题吧.本篇文章主要根据实际开发中遇到的需求,讲解使用 Gradle 对应用的不同版本进行个性化定制. 场景介绍 一般的应用基本上都有正式服和测试服,这个就不需要多说了.但是有些应 ...

  10. jenkins主从从服务器发布脚本执行成功但总提示失败 FATAL: Remote call on XXXX failed

    主从jenkins当调用 slave 执行编译脚本后提示如下错误,找了半天怎么也没有问题,后来忽然发现slave上java的版本和master不同,一个 1.8 一个 1.10,将slave降回1.8 ...