转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
我的文章-《剖析Delphi中的多态》         ★★★★

我的文章-《剖析Delphi中的多态》

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1571 更新时间:2009/4/23 18:30:21
   {*****************************声  明***********************************
    用派生类指针/引用指向基类对象实现的多态。是一种病态的多态!
    这种多态的使用方法,它就象一个实际很小的事物(基类对象)披上一个强大
    的外表(派生类引用),因而带来了许多潜在的不安全因素(如访问异常),所
    以几乎没有任何价值。"杜撰"这样一个例子,旨在说明在Delphi中的多态的本质,多态的本质:使用一个合法的(通常是基类的)指针/引用来操作对象,在运行期根据实际的对象,来执行不同的操作方法,或者更形象的说法:由对象自己来决定自己操作方式,编译器只需下达做什么的命令(做什么what),而不要管怎么做(how),"怎么做"由为对象自己负责。这样实现了接口和实现的分离,使接口重用变得可能。
   ***********************************************************************}

  cppProgramer:=TCppProgramer(TProgramer.Create);
   {为了实现这种病态的多态,把对象引用强制转换为TCppProgramer类型,
    从而逃过编译器的检查}
  cppProgramer.startWorking;
   {调用的TProgramer.startWorking而不是TcppProgramer.startWorking
    这就是用派生类指针/引用指向基类对象实现的多态。}
  cppProgramer.Free;

  cppProgramer:=TCppProgramer(TDocManager.Create);
  cppProgramer.startWorking;
  {调用的竟然是TDocManager.startWorking,
   这就是用派生类指针/引用指向基类对象实现的多态。这种方法极不安全,
   而且没有什么必要}
  cppProgramer.Free;
end;
 试一试
为获得这种多态的感性认识,建议动手试试,上面说到这种使用方法会有潜在的不安全性(如访问异常),而上面的程序运行一点错误都没有出现,想想为什么?什么情况下会出现访问异常,动手写个访问异常的例子,你将收获更多。(参考Demo程序)
2 VCL中多态的应用
2.1构造与析构方法
构造方法的多态
由于构造方法可以看作“特殊的”类方法,在Tcomponent之后的所有的派生类的又被重新定义为虚类方法,因此要实现构造方法的多态性,就得使用类引用,在Delphi中有个经典的例子,就在每一个工程文件中都有一个类似下面的代码:
Application.CreateForm(TForm1, Form1);
其方法的定义:
procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);
var// InstanceClass为类引用。
  Instance: TComponent;
begin
  Instance := TComponent(InstanceClass.NewInstance);
{NewInstance方法的声明:class function NewInstance: TObject; virtual; (system单元 432行)是一个类方法,同时也是虚方法,我们把它称之为虚类方法。InstanceClass是一个类引用,实现了类一级的多态,从而实现了创建组件的接口重用}
  TComponent(Reference) := Instance;
  try
    Instance.Create(Self);//调用构造方法,进行初始化
  except
    TComponent(Reference):= nil;//消除“野“指针!good
    raise;
  end;
  {如果创建的是窗口且还没有主窗体的话,就把刚创建的窗体设为主窗体}
  if (FMainForm = nil) and (Instance is TForm) then
  begin
    TForm(Instance).HandleNeeded;
    FMainForm := TForm(Instance);//设置主窗体
    { 实际上,在项目选项(project->options)中设置主窗体,实际上就把工程文件中相应的窗体语句提到所有创建窗体语句之前。}
  end;
end;
2) 析构方法的多态请参考《剖析Delphi中的构造和析构》,第3.3节
2.2 Tstrings
字符串数组处理在Delphi的控件中十分常见,通常是一些Items属性,我们用起来也特别地方便(因为都是一样的使用接口),这得益于Delphi中字符串数组的架构的设计。这是一个成功的设计。
由于很多控件中要用到字符串数组,如ComboBox,TstringGrid等等,但每个控件中的字符串数组又不同,Delphi由此把字符串数组但抽象出来,从而出现了很多与之相关的类。其中基类Tstrings只是提供为各种调用提供接口,具体实现完全可由其派生类中实现,因此,把Tstrings定义为抽象类。
下面就来看看基类TStrings类的常用方法的定义(参见Classes单元第442行):
  TStrings = class(TPersistent)
  protected
    ...
    function   Get(Index: Integer): string; virtual; abstract;
    procedure  Put(Index: Integer; const S: string); virtual;
    function   GetCount: Integer; virtual; abstract;
    …
  public
    function  Add(const S: string): Integer; virtual; //实际调用的是Insert
      {添加一字符串S到字符串列表末尾}
    procedure AddStrings(Strings: TStrings); virtual;
      {添加字符串列表Strings到该字符串列表末尾}
    procedure Insert(Index: Integer; const S: string); virtual; abstract;
      {抽象方法,在第Index位置插入一新字符串S}
    procedure Clear; virtual; abstract;
      {清除所有的字符串}
    procedure Delete(Index: Integer); virtual; abstract;
      {删除某个位置上的字符串}
    function  IndexOf(const S: string): Integer; virtual;
      {获取S在字符串列表中的位置}
    function  IndexOfName(const Name: string): Integer; virtual;
      {Returns the position of the first string with the form Name=Value with the specified name part}
    function IndexOfObject(AObject: TObject): Integer; virtual;
{获取对象名为AObject:的对象在字符串列表中的位置}
    procedure LoadFromFile(const FileName: string); virtual;
      {Fills the list with the lines of text in a specified file}
    procedure LoadFromStream(Stream: TStream); virtual;
      {Fills the list with lines of text read from a stream}
    procedure SaveToStream(Stream: TStream); virtual;
      {Writes the value of the Text property to a stream object}
    property Strings[Index: Integer]: string read Get write Put; default;
      {References the strings in the list by their positions}
    property Values[const Name: string]: string read GetValue write SetValue;
{Represents the value part of a string associated with a given Name, on strings with the form Name=Value.}
    …
  end;
从Tstrings的定义可以看出,它的大部分Protected和Public的方法都是虚方法或是抽象方法。(请Soul来补充一些,TstringList->TstringGridString)
2.3其他(请soul来补充)
如果你对多态还不明白的话,那请你记住多态的实质:
“相同的表达式,不同的操作”(就这么简单)
从OOP语言的实现来讲,多态就是使用基类的指针/引用来操作(派生类)对象,在运行期根据实际的对象,来执行不同的操作方法;或者换一种更形象的说法:由对象自己来决定自己操作方式,编译器只需下达做什么的命令(做什么what),而不要管怎么做(how),"怎么做"由为对象自己负责。这样就实现了接口和实现的分离,使接口重用变得可能。
其实多态也简单!那么使用多态应该注意什么呢?下面我的两点几点建议:
分析业务逻辑,然后把相关的事物抽象为“对象”,再用对象方法封装业务逻辑。把一些具有多态性的操作,在基类中声明为虚方法(virtual Method),对于在基类没有必要实现的就声明为抽象方法(virtual Abstract Method),然后在其派生类中再覆载它(Override),在使用的时候用基类的引用/指针来调用,这样顺理成章地实现了现实世界中的多态性。记住千万不要为了多态,而去实现多态,这是一种走形式化的做法,是没有意义的。
由于基类与派生类有一种天然“耦合”关系,修改基类就会导致“牵一发而动全身”,这将是非常麻烦的事情!因此要尽量弱化基类的功能实现,必要时把它设计为“抽象类”,并保证稳定的接口,这可以通过预留一些冗余的虚函数(或抽象函数)来实现。
相关问题
讨论Delphi的多态: http://www.delphibbs.com/delphibbs/dispq.asp?lid=1753965
关于多态性: http://www.delphibbs.com/delphibbs/dispq.asp?lid=1854895
什么是多态?在日常编程中有哪些运用?http://www.delphibbs.com/delphibbs/dispq.asp?lid=960465
overload 与 override有何区别,请执教?http://www.delphibbs.com/delphibbs/dispq.asp?lid=296739
派生类的指针指向基类对象的问题 http://www.delphibbs.com/delphibbs/dispq.asp?lid=2104106
(最后一个问题是我在深入学习多态时在DelphiBBS上提的,曾引起热烈的讨论,建议看看)

上一页  [1] [2] 


[Delphi程序]我的文章-《剖析Delphi中的构造和析构》  
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台