重温Delphi之:面向对象

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

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

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

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

ExpandedBlockStart.gif 代码
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

ExpandedBlockStart.gif 代码
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

ExpandedBlockStart.gif 代码
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接口

ExpandedBlockStart.gif 代码
unit  UICook;

interface

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

implementation

end .

5.放到ConsoleApplication中测试一把:

ExpandedBlockStart.gif 代码
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接口,所以我会做饭:)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值