|
Delphi对象模型 (PART IV)
Delphi对于面向对象编程的支持丰富而且强大。除了传统的类和对象,Delphi还提供了接口,异常处理,多线程编程等特性。这一章节深入讲解了Delphi的对象模型。读者应当对标准的Pascal比较熟悉,并且对有关面向对象编程的基本法则有一定了解。
(本文的英文原文将Delphi与Object Pascal统一表述为Delphi,可能有概念不清之嫌疑。但在大多数情况下,相信读者能够根据上下文来判定文中所述之Delphi的具体含义——译者注。)
Object Life Cycle对象的生命周期
对于绝大多数对象,你调用构造器创建它,使用它,然后调用Free将它释放。Delphi替你处理了所有其他细节。或许,有时,你需要了解更多有关Delphi对象模型内部的实现机制。例2-8显示的是用于模拟Delphi创建和释放一个对象的方法。
例 2-8:对象的生命周期 type TSomething = class procedure DoSomething; end; var Ref: TSomething; begin Ref := TSomething.Create; Ref.DoSomething; Ref.Free; end; //在构造器中被隐藏代码类似于这样: function TSomething.Create(IsClassRef: Boolean): TSomething; begin if IsClassRef then try //获得新的对象实例 Self := TSomething.NewInstance; //NewInstance初始化对象,功能与InitInstance类似。假如你覆盖了NewInstance,那么, //不要调用inherited NewInstance,而应当调用InitInstance。 //这个调用正如下面所示,因此你可以知道究竟发生了什么, //但是请记住通常Delphi实际上并不调用InitInstance。 InitInstance(Self); //做构造器真正要做的工作,无需用到类引用。 //注意,Delphi并不真的对构造器进行递归调用。 Self.Create(False); Self.AfterConstruction; except //若有任何异常发生,Delphi自动调用对象的析构器。 Self.Destroy; end else Self.Create(False); Result := Self; end; //构造器中被隐藏的代码类似于这样: procedure TSomething.Destroy(Deallocate: Boolean); begin if Deallocate then Self.BeforeDestruction; // Delphi并不真的递归调用析构器,但这里是析构器真正发生作用的地方。 Self.Destroy(False); if Deallocate then begin // Delphi并不真的调用CleanupInstance而是调用FreeInstance来做清理的工作。 // 假如覆盖了FreeInstance,不要调用inherited FreeInstance,而应当调用CleanupInstance // 来清理字串、动态数组以及可变类型字段。 Self.CleanupInstance; //调用FreeInstance来释放对象占用的内存。 Self.FreeInstance; end; end;
Access Levels访问级别
类似于C++和Java,Delphi提供了不同的访问级别控制机制,来决定一个对象是否能其他对象的字段,方法,以及属性等。访问级别分为以下几种:
private 私有的 私有的方法,只能被该类自己的方法以及在同一单元的实现部分中定义的方法、过程和函数访问。Delphi没有C++风格的友类声明也没有Java风格的包级别上的访问控制(package level access)。在Delphi中与之等同的是将包或者友类在同一单元声明,这样该单元中的所有类的私有及受保护部分都可以被访问。
protected 受保护的 受保护的方法,可以被该类以及派生类的任何方法访问。派生的类可以处于不同的单元中。
public 公用的 公开的方法没有访问限制。任何方法,函数,或者过程都可以访问公用声明的部分。除非使用$M+编译指示符,否则缺省的访问级别是公用的。
published发布的 发布的声明与公用的声明基本上相同,唯一的不同是Delphi为发布的声明保存运行时间信息。有些声明不能是发布的;详见第三章内容。如果类或者基类使用$M+指示符,则缺省的访问级别为发布的。
提示: Delphi的IDE在Form最开始没有命名的部分声明字段和方法。因为TForm继承自TPersistent,而在TPersistent中使用了$M+指示符,因此最开始部分的访问级别为发布的published。换句话说,IDE将字段和方法声明为发布的。当Delphi装载一个Form描述文件(.dfm文件)时,它依赖于发布的信息来创建该Form对象。IDE依赖于Form类的最开始未命名部分的声明。假如你修改那一部分的东西,可能会有导致IDE的Form编辑器不可用的危险。
automated 自动的 自动的声明与公开的声明很接近,唯一的不同就是Delphi将保存更多的运行时间信息以支持OLE自动化服务。自动化的声明已经成陈旧了;你可以转而使用Delphi的类型库编辑器,但现在,他们为了向后兼容而保留了一部分。Delphi的下一版本可能会将这些部分彻底根除。第三章更进一步的阐述有关自动类型的声明。
派生的类可以提高属性的访问级别。通过在新的访问级别上重新声明属性来做到这一点(比如将首受保护的改为公开的)。但是不能降低一个属性的访问级别,并且你不能改变一个字段或者方法是否可见。你可以通过覆盖一个虚方法,或者声明一个覆盖方法在同样或者更高一级的访问级别上,但你不能降低访问级别。
Hiding a Constructor隐藏构造器
有时,一个类不用做公用的用途,而只是作为其他类的一个辅助类。这种情况下,你可能希望该辅助类的Create是私有的或者是受保护的,但这需要技巧。TObject声明了一个公开的构造器:Create.因此即使该辅助类的构造器是私有的或者受保护的,你依然可以调用自TObject继承而来的Create构造器。
尽管你不能改变继承来的Create构造器的访问权限,你还是可以通过另外一个公开的构造器来隐藏它。因为假如派生的构造器被调用,将引发一个异常。如下例: type TPublic = class; TPrivateHelper = class private //TPublic是唯一一个被允许调用真正的构造器的类 constructor Create(Owner: TPublic); overload; public [1] [2] [3] 下一页 [VB.NET程序]VB.Net中文教程(13) Whole-Part关系 [Delphi程序]The Delphi Object Model (PART III) [Delphi程序]The Delphi Object Model (PART II) [Delphi程序]The Delphi Object Model (PART I) [Delphi程序]Delphi对象模型(Part III) [Delphi程序]Delphi对象模型(Part II) [Delphi程序]Delphi对象模型(Part I) [Delphi程序]Delphi对象模型(Part V) [Delphi程序]Delphi对象模型(Part VI) [Delphi程序]防止全局hook入侵Delphi版,2000以上系统适用(pa…
|