重温Delphi之:面向对象

任何一门语言,只要具备了"封装,继承,多态"这三项基本能力,不管其实现方式是直接或曲折、复杂或简洁,就可以称之为“面向对象”的语言。

Delphi当年的迅速走红,是以其RAD快速开发吸引程序员的目光。这无疑是它最吸引人的优势,但同时也让人误以为delphi只是vb的高级版本,从而忽视了其面向对象的特性。

其实Pacscal发展到Delphi,已经完全具备了面向对象的所有特点:允许自定义类,类可以继承(单继承),允许方法重载/覆写,可以定义接口,类可以实现接口,允许定义静态方法(即class方法),虚方法,抽象类...等等,对于delphi怀有偏见的朋友,你还会怀疑delphi的面向对象能力吗?

下面是一些演示代码:
1.先定义一个基类TPeople

代码
unit UPeople;

interface

type
  TPeople 
= class(TObject)
  
  
private
    _name:
string//私成成员定义
    
procedure Set_Name(value:string);//Name属性的set方法定义
    
function Get_Name:string//Name属性的get方法定义

  
protected
    
function Get_Sex:Boolean;virtual;abstract//定义抽象虚方法,由子类去实现
    
  
public
    
property Name:string read Get_Name write Set_Name; //定义Name属性
    
property Sex:Boolean read Get_Sex; //定义Sex只读属性(该属性并未实现,而是交由子类去实现)
    
class function ToString:string//类方法,有点象c#中的static静态方法 
    
procedure ShowName;//公用实例方法    
end;

//实现部分
implementation

    
procedure TPeople.Set_Name(value:string);
    
begin
      _name :
= value;
    
end;

    
function TPeople.Get_Name:string;
    
begin
      result :
= _name;
    
end;

    
class function TPeople.ToString:string;
    
begin
      result :
=  'This is a People Class';
    
end;

    
procedure TPeople.ShowName;
    
begin
      Writeln(
'姓名:' + _name);
    
end;    
end.

2.再定义一个子类TMan

代码
unit UMan;
   
interface

uses
     UPeople ;
   
type
  TMan 
= class(TPeople)

  
constructor Create(name:string); overload ; //重载构造函数

  
  
private
    _sex:Boolean;

  
protected
    
function Get_Sex:Boolean; override;


  
public
    
function ToString:string//实例方法

  
end;

implementation

  
constructor TMan.Create(name:string); //注意写法:实现的时候不用加overload关键字
  
begin
     
inherited Create;
     _sex :
= true; //男性强制定义为true
     Self.Name :
= name;
     
  
end;

  
function TMan.Get_Sex:Boolean;
  
begin
    result :
= _sex;
  
end;

  
function TMan.ToString:string;
  
begin
    result :
= '这是TMan中的ToString方法';
  
end;

    
end.

3.再来一个子类TWoman

代码
unit UWoman;

interface

uses
     UPeople,UICook;
   
type
  TWoman 
= class(TPeople,ICook)

  
constructor Create(name:string); overload ;

  
  
private
    _sex:Boolean;

  
protected
    
function Get_Sex:Boolean; override;

  
public
    
procedure Cook;//接口的方法实现定义
    
procedure ShowName;overload;

    
//如果Class是从TObject继承的,又想实现接口的话,必须实现下面这三个function,
    
//如果想偷懒的话,把UPeople改成从TInterfacedObject继承就可以省掉这个步骤了
    
function _AddRef:Integer; stdcall;
    
function _Release:Integer;stdcall;
    
function QueryInterface(const IID:TGUID;out Obj):HResult; stdcall;
  
end;

implementation

  
function TWoman._AddRef:Integer;
  
begin
      result :
=-1;
  
end;

  
function TWoman._Release:Integer;
  
begin
      result :
=-1;
  
end;

  
function TWoman.QueryInterface(const IID:TGUID;out Obj):HResult;
  
const
      E_NOINTERFACE 
= $80004002;
  
begin
      
if   GetInterface(IID,Obj) then
          Result :
= 0
      
else
          Result :
= -1{E_NOINTERFACE}
  
end;   

  
  
constructor TWoman.Create(name:string);
  
begin
     
inherited Create;
     _sex :
= false;
     Self.Name :
= name;     
  
end;

  
function TWoman.Get_Sex:Boolean;
  
begin
    result :
= _sex;
  
end;

  
procedure TWoman.ShowName;
  
begin
    Writeln(
'女人总是喜欢搞点花样,所以重载一下哈.')
  
end;

  
procedure TWoman.Cook;
  
begin
    Writeln(
'因为我实现了ICook接口,所以我会做饭:)')
  
end;

end.

注意,TWoman这个子类实现了接口ICook,其定义如下:

4.ICook接口

代码
unit UICook;

interface

type
  ICook 
= interface //定义一个接口
  
procedure Cook;//接口的方法定义 
  
end;

implementation

end.

5.放到ConsoleApplication中测试一把:

代码
program ClassDemo;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  UPeople 
in 'UPeople.pas',
  UMan 
in 'UMan.pas',
  UWoman 
in 'UWoman.pas',
  UICook 
in 'UICook.pas';

var
  aPeople:TPeople;
  aMan:TMan;
  aWoman:TWoman;
  aCook:ICook;

begin
  aPeople :
= TPeople.Create;
  aPeople.Name :
= 'jimmy.yang';
  Writeln(aPeople.Name);
  Writeln(TPeople.ToString);
//调用静态方法
  aPeople.ShowName;

  Writeln(
'----------------------------------------');
  
  aMan :
= TMan.Create('杨俊明');
  Writeln(aMan.Name);
  Writeln(aMan.Sex);
  aMan.ShowName; 
//通过继承得来的方法
  Writeln(aMan.ToString);
//TMan实例中的对象方法

  Writeln(
'----------------------------------------');

  aWoman :
= TWoman.Create('小龙女');
  Writeln(aWoman.Name);
  Writeln(aWoman.Sex);
  aWoman.ShowName; 
//调用重载后的方法
  aWoman.Cook;
//实现接口得来的方法   
  Writeln(
'----------------------------------------');
  aCook :
= ICook(aWoman);//类还可以转化为接口
  aPeople.Free;
  aPeople:
= TWoman.Create('翠花'); //同样也允许子类创建得到父类
  aPeople.ShowName;
  aWoman.Free;
  aWoman :
= TWoman(aPeople);
  aWoman.Cook;
  Readln;
end.

 

运行结果:
jimmy.yang
This is a People Class
姓名:jimmy.yang
----------------------------------------
杨俊明
TRUE
姓名:杨俊明
这是TMan中的ToString方法
----------------------------------------
小龙女
FALSE
女人总是喜欢搞点花样,所以重载一下哈.
因为我实现了ICook接口,所以我会做饭:)
----------------------------------------
姓名:翠花
因为我实现了ICook接口,所以我会做饭:)

 

posted @ 2009-12-15 19:37  菩提树下的杨过  阅读(2339)  评论(0编辑  收藏  举报