剖析Delphi中的多态、继承,覆盖

来源:互联网 发布:windows 搭建http代理 编辑:程序博客网 时间:2024/05/21 04:40
 

1什么是多态?
1.1概念
1.2多态的意义
1.3多态在delphi中如何实现的?
1.3.1 继承(Inheritance)
1.3.2 虚方法、动态方法与抽象方法,VMT/DMT,静态绑定与动态绑定
1.3.3 重载(Overload)与多态
1.4多态种类的探讨
1.4.1 两级多态
1.4.2 不安全的多态
2 VCL中多态的应用
2.1构造与析构方法
2.2 Tstrings
2.3其他(请soul来补充)

多态是面向对象的灵魂所在,理解多态是掌握面向对象技术的关键之一。但是到底什么是多态?多态有何意义?怎么实现多态?多态的概念我能懂,但不知道如何使用以及什么时候该使用呢?请看本文细细道来?

不同的操作  —根据不同的对象就有不同的操作。
举个例子来说明,比如在公司中有各种职责不同的员工(程序员,业务员,文管等),他们“上班”时,做不同的事情(也可以看作是一种业务逻辑),我们把他们各自的工作都抽象为"上班",关系如下:

                    员工
                  /       ——继承关系
           程序员业务员 文管

每天上班时间一到,相当于发了一条这样的命令:
  “员工们.开始上班”(同一条表达式)
每个员工接到这条命令(同样的命令)后,就“开始上班”,但是他们做的是各自的工作,程序员就开始“Coding”,业务员就开始“联系业务”,文管员就开始“整理文档”。即“相同的表达式(函数调用),(在运行期根据不同的对象来执行)不同的操作”。
从语言实现多态的角度来说,多态是通过基类指针或引用指向派生类的对象,调用其虚方法实现的。下面是Object Pascal语言的实现
TEmployee=class    //把员工抽象为一个抽象类
  public
    procedure startWorking;virtual;abstract;
{抽象函数(即C++中纯虚函数),什么也不做,实际的意义是,先预留一个接口。在其派生类中覆载实现它。}
  end;

  TProgramer=class(TEmployee)     //程序员
  public
    procedure startWorking;override;
  end;

  TBusinessMan=class(TEmployee)  //业务员
  public
    procedure startWorking;override;
  end;

  TDocManager=class(TEmployee)  //文管
  public
    procedure startWorking;override;
  end;
procedure TProgramer.startWorking;
begin
  showmessage('coding');
end;

{ TbusinessMan }

procedure TbusinessMan.startWorking;
begin
  showmessage('Linking Business');
end;

{ TDocManager }

procedure TDocManager.startWorking;
begin
  showmessage('Managing Document');
end;

procedure TForm1.Button1Click(Sender: TObject);
const
  eNum=3;
var
  Employee:array of TEmployee;
  i:integer;
begin
  setLength(Employee,eNum);
  Employee[0]:=TProgramer.Create; 
//把基类引用employee[0]指向刚创建的TProgramer对象
  Employee[1]:=TBusinessMan.Create;
  //把基类引用employee[1]指向刚创建的TBusinessMan对象
  Employee[2]:=TDocManager.Create;
    //把基类引用employee[2]指向刚创建的TDocManager对象
  for i:=0 to Length(Employee)-1 do
    Employee[i].startWorking; //在运行期根据实际的对象类型动态绑定相应的方法。
{从语言实现多态的角度来说,多态是通过基类指针或引用指向派生类的对象,调用其虚方法来实现的。Employee []为基类对象引用数组,其成员分别指向不同的派生类对象,当调用虚方法,就实现了多态}
end;
虚方法
虚方法,表示一种可以被覆载(Override)的方法,若没有声明为抽象方法,就要求在基类中提供一个默认实现。类中除存储了自己虚方法指针,还存储所有基类的虚方法指针。
声明方法:
  procedure 方法名;virtual;
这样,相当于告诉Delphi编译器:
可以在派生类中进行覆载(Override)该方法,覆载(Override)后还是虚方法。
不要编译期时确定方法的入口地址。而在运行期,通过动态绑定来确定方法的入口地址。
在基类中提供一个默认实现,如果派生类中没有覆载(Override)该方法,就使用基类中的默认实现。
动态方法
动态方法和虚方法本质上是一样的,与虚方法不同的是,动态方法在类中只存储自身动态方法指针,因此虚拟方法比动态方法用的内存要多,但它执行得比较快。但这对用户完全是透明的。
声明方法:
  procedure 过程名;dynamic;
抽象方法
一种特殊的虚方法,在基类它不需提供默认实现,只是一个调用的接口用,相当于C++中的纯虚函数。含有抽象方法的类,称之为抽象类。
声明方法:
  procedure 过程名;virtual;abstract;