DELPHI面向对象参考 (转)

DELPHI面向对象参考

 

一、类和对象

类是对象的类型,是创建对象的模板。一个类可以创建多个对象,而一个对象总是属于某个类。类具有内部的属性(状态)和行为(操作)。

对象是类的实例,具有区别于同类其他对象的属性集合。

对象的声明存放于堆栈,对象的引用存放于堆。

二、类的方法分类

1、  普通方法

不加任何修饰的方法为普通方法。普通方法必须调用类的实例进行访问。即必须

建类的对象,调用方式为:对象.方法,声明方式为:

procedure[function] 方法名(参数表)[:返回值];

 

2、  构造方法

构造方法用于创建类的实例,调用后返回类的句柄。构造方法可以有多个版本。声明方式是:

          constructor 构造方法名(参数表);

 

3、  析构方法

析构方法用于销毁类的实例,一般不建议直接调用析构方法,而采用调用对象.Free的方式进行对象释放。声明方式为:

destructor 析构方法名(参数表);

 

4、  类方法

类方法属于一个类,在运行时即存在于内存中。可使用类.方法的方式进行调用,即不需要创建类的实例。声明方式是在普通方法前加class

class procedure[function] 方法名(参数表)[:返回值];

 

5、  消息处理方法

消息处理方法和一个唯一的消息ID进行关联,用于响应动态分派的消息。声明方式:

procedure 方法名(消息变元);message 消息ID;

三、多态、继承、重载

1、  静态方法

静态方法由对象的类决定。属于“早期联编”,即在编译阶段就决定了方法的实现版本。一个类的实例可创建为其他类的实例,但是调用到同名方法时,使用的方法是声明该实例的类的静态方法,声明方式:

procedure[function] 方法名(参数表)[:返回值];

2、  虚拟方法

虚拟方法可实现“后期联编”,即在程序运行时可动态调用不同的方法版本,实现多态。所有类的虚拟方法在内存中建立了一张VMT(虚拟方法表),在调用时动态定位方法函数的位置。比动态方法多占用内存空间,但是速度较快。声明方式:

procedure[function] 方法名(参数表)[:返回值];virtual;

3、  动态方法

虚拟方法可实现“后期联编”,即在程序运行时可动态调用不同的方法版本,实现多态。本类的动态方法在内存中建立了一个DMT(动态方法表),在调用时根据动态方法唯一的编号定位方法地址。比虚拟方法少占用内存,但是速度较慢(因为可能用到祖先类的动态方法)。声明方式:

procedure[function] 方法名(参数表)[:返回值];dynamic;

4、  抽象方法

抽象方法不提供方法的实现脚本。只提供一个方法的签名(方法名称、参数表、返回值)。一般在高级别类中使用抽象方法。派生类对抽象方法进行覆盖、重载实现抽象方法脚本。使用抽象方法,必须创建实现了抽象方法的类(一般为派生类)才可使用。因为抽象方法也属于“后期联编”,因此必须和虚拟方法、动态方法结合,声明方式:

procedure[function] 方法名(参数表)[:返回值];virtual;abstract;

procedure[function] 方法名(参数表)[:返回值];dynamic; abstract;

 

抽象方法提供了一种从高层次视图观察对象的方式

5、  方法覆盖

在父类中生命的静态方法、虚拟方法、动态方法,都可在派生类中进行同名签名登记。这将覆盖父类的这些方法。提供更特殊的功能,声明方式:

procedure[function] 方法名(参数表)[:返回值];override;

 

方法的覆盖提供了对类的多态性

6、  方法重载

在父类中生命的静态方法、虚拟方法、动态方法,都可在派生类中进行同名签名登记,但是需要不同的参数表。这将重载父类的这些方法。提供更特殊的功能,声明方式:

procedure[function] 方法名(参数表)[:返回值];overload;

 

方法的重载提供了对类的扩充性

四、reintroduceselfisas

1、  reintroduce

当父类中以定义了一方法,派生类再定义同签名的方法将会隐藏父类的方法,如果不希望这种结果出现,可在派生类定义方法时,加此标志,声明方式:

procedure[function] 方法名(参数表)[:返回值];reintroduce;

2、  self

self代表了实例对象自身。类的所有数据成员和函数成员都隐含存在于with self do结构范围内。使用方法:

self.Edit1.text:=’’;

 

3、  is

is用于进行实例对象的类型检查,以Boolean返回是否是该类实例(或派生类实例),使用方法:

if Edit1 is Tedit then …

 

4、  as

as用于进行对象的强制类型转换,一般适用于子类向父类的转换(特殊→一般),而从父类到子类的转换可能失败。在使用时,可结合is进行判断,使用方式:

if Sender is Tedit then (Sender as TEdit).Text:=’’;

 

五、类内部成员可见性

1、  类具有privatepublicprotectedpublished4中访问属性。访问属性是指其他类对该类对象的可操作性,可读写性,以及其他类对本类中类方法(函数)的可操作性

2、  private:本类内部使用;声明在同一单元的其他类可使用

3、  public:本类、本类派生类、其他类都可访问

4、  protected:本类、本类派生类可访问。其他类不可访问

5、  published:所有类都可访问。

综合举例:

TClass1=class

private

  {内部数据/状态储存声明}

  FName: string;

  FAge: Integer;

  {内部属性写方法声明}

  procedure SetAge(const Value: Integer);

protected

  {保护虚方法声明}

  procedure Eat;virtual;

public

  {公有属性/状态储存声明}

  Sex: string;

published

  {公共属性发布声明}

  {构造函数}

  constructor create;

  {具有读/写方法的属性声明}

  property Name:string read FName write FName;

  property Age: Integer read FAge write SetAge;

end;

TClass2=class

private

  FSex: string;

published

  constructor create;

end;

TClass11=class(TClass1)

public

  {覆盖了父类中同名的方法,提升了方法的可见性}

  procedure Eat;override;

end;

 

 

{ TClass1 }

 

 

constructor TClass1.create;

begin

end;

 

 

procedure TClass1.Eat;

begin

 

 

end;

 

 

procedure TClass1.SetAge(const Value: Integer);

begin

  FAge := Value;

end;

 

 

{ TClass2 }

 

 

constructor TClass2.create;

var

  c2:TClass2;

begin

  c2:=TClass2.create;

  c2.FSex:='';

  FreeAndNil(c2);

end;

 

 

{ TClass11 }

 

 

procedure TClass11.Eat;

begin

  inherited;

 

 

end;

 

 

UML-类图:

6、  派生类可提升父类的可见性,却不可降低父类的可见性

六、对象、对象引用、类引用、参数传递

1、  对象之间通过消息传递(参数),进行互操作,使用其他类提供的服务(方法组合);消息即对另一对象方法的调用或属性读写

2、  对象分配在堆中、普通数据类型分配在栈中

3、  对象名代表了该对象在栈中的位置,该位置存储的是对象在堆中的实际地址;普通变量名代表了该变量在栈中的位置,该位置存储的是具体数据,而该数据可能是其他变量/对象的地址

4、  值参传递:传递的是具体的数值,进行处理后不会改变原值,其实传递的是该数据的一个副本

5、  引用传递:传递的是对该变量/对象的地址引用,处理后可能会改变原值,传递的是同一个变量/对象的地址

6、  类引用:类的类,形式为“class of type”,其中type代表该类可引用的类元类型。

七、对象的创建、使用、销毁

1、  创建:Create Tobject提供的默认构造函数,若从Tobject继承创建的类,自动继承该方法

2、  销毁:DestroyTobject提供的默认析构函数,若从Tobject继承创建的类,自动继承该方法

3、  使用:可使用if Assigned (对象名) 判断该对象是否存在;使用FreeAndNil(对象名)释放对象

4、  克隆:继承自Tpersistent的类对象都具有克隆功能。使用对象2.Assign(对象1)的方式克隆

5、  对象的属主:当对象拥有属主时,其生命周期由属主对象进行管理,无属主的对象需要进行手工管理。

6、  对象的创建:先继承父类创建,再完成自身的创建

7、  对象的释放:先释放自身,在完成父类的继承释放

八、类及对象间的关系

1、  继承:子类继承了父类的所有保护、公有、发布部分的数据成员及函数/过程成员

2、  重载:不是类的特有。提供一个同名但参数不同的函数/过程,具有多个实现版本

3、  覆盖:子类通过继承父类的函数/过程,重新定义了功能实现

4、  引用:一个对象内部定义了另一个对象变量,即为引用关系

5、  合成:对象内的各组成部分依赖于某一主体属性而同生共灭

6、  聚合:对象内的各组成部分属于零散的简单组合关系,使用不同的服务组合成一个整体的功能

九、接口

1、  接口:具有某种特定的属性及函数/过程签名的定义,而没有实现。不具备内部数据成员。功能的调用是通过创建实现其功能签名的派生类完成的

2、  接口必须具备3个方法:_AddRef/_Release/QueryInterface,最简单的方式是从TinterfacedObject继承

3、  接口使用演示:

IInterface=interface

['{02960574-2025-46C3-9882-F79C3C67EA99}']

  function GetName:string;

  procedure Eat;

end;

 

 

TPerson=class(TInterfacedObject,IInterface)

private

  FName: string;

public

  function GetName:string;virtual;

  procedure Eat;dynamic;

  procedure SayHello;virtual;abstract;

published

  constructor create;

  destructor destory;

  property Name:string read FName write FName;

end;

 

 

TChinese=class(TPerson,IInterface)

public

  procedure SayHello(str:string);overload;

  procedure SayHello;overload;override;

published

  constructor create;

  destructor destory;

end;

 

 

{ TPerson }

 

 

constructor TPerson.create;

begin

  ShowMessage('TPerson.create');

end;

 

 

destructor TPerson.destory;

begin

  ShowMessage('TPerson.destory');

end;

 

 

procedure TPerson.Eat;

begin

  ShowMessage('TPerson.Eat');

end;

 

 

function TPerson.GetName: string;

begin

  result:='TPerson.GetName';

end;

 

 

{ TChinese }

 

 

procedure TChinese.SayHello(str: string);

begin

  ShowMessage('TChinese.SayHello('+str+')');

end;

 

 

constructor TChinese.create;

begin

  ShowMessage('TChinese.create');

end;

 

 

destructor TChinese.destory;

begin

  ShowMessage('TChinese.destory');

end;

 

 

procedure TChinese.SayHello;

begin

  //inherited;

  ShowMessage('TChinese.SayHello');

end;

 

 

procedure TForm1.Button2Click(Sender: TObject);

var

  FMan:TPerson;

begin

  FMan:=TChinese.create;

  FMan.SayHello;

  FMan.Free;

end;

4、   

 

十、 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值