我的Delphi7里程碑(认识Object Pascal 面向对象(OOP))

Delphi7的应用

(当光标位于类定义中时,如果按下ctrl+shift+c组合键,Delphi编辑器的类自动生成此方法的实现结构)

 

一.关于方法的更多处理:

1.       Delphi支持overloading方法.如果使用overload关键字标志该方法,你就可以有两个具有相同名字的方法,而且两个方法的参数列表必须是不同的.通过检查参数,编译器可以确定用户想调用哪个方法.(重载)

2.       方法可以有一个或多个带有默认值的参数.如果这些参数在方法调用时被忽略,它们将会得到默认值.(默认参数)

3.       在一个方法中,可以使用Self关键字访问当前对象.(相当于c++this)

4.       默认情况下,方法使用register调用约定:参数和返回值要从调用代码传递到函数中.这个过程可以使方法调用更快捷.

 

 

二.封装:

 对于类的封装来说,Delphi使用了四个访问标识符:private, public, protected, published

 

用属性封装(property)

       属性就是用一个名称来完全隐藏它的实现细节.这使得程序员可以任意修改类,而不会影响使用它的代码.属性就是虚拟字段.属性可以直接与数据以及访问对象的方法对应起来,用于读写数值.

例如:month字段的属性

Property Month: Integer read FMonth write FMonth;

Property Monty: Integer read GetMonth write SetMonth;

 

属性的高级应用:

属性需要公布的访问标识符声明,在published关键字中进行声明.

通常可以向一个属性赋予一个值或读取它,甚至在表达式中使用属性,但是不能将属性作为参数传递给过程和对象方法,这是因为属性不是一个内在位置,所以它不能被用做varout参数,也不能通过引用传递.

 

构造器(constructor Create):

在构造器前面就使用constructor关键字.尽管可以为一个构造器使用任何名称,但还是应该坚持使用标准名称,Create.

通过使用一些参数定义Create构造器,可以用新定义代替默认定义并强制使用它.(可以定义多个构造函数)

 

析构器和Free方法:

在析构器前面使用destructor关键字.用标准名字Destory

Free释放对象,可以使用FreeAndNil(Obj)来完成Freenil的过程

 

三.Delphi的对象引用模型:

       在一些OOP语言中,可通过声明一个类的变量建立该类的实例,而Delphi则不同,它以对象引用模型为基础.它的基本思想是,类的每个变量,并不会保存对象的值,而是保存一个引用或一个指针,以说明对象被存储在内在位置.

       使用这种方法唯一的问题是,当声明一个变量时,不会建立一个对象,而只是保存一个对象引用的内在地址,对象实例必须人工建立,至少对于用户自己定义的类的对象如此.一旦建立了一个对象并完成了使用,就需要解除它,可以通过调用Free对象方法来实现.

(C++里面的指针,要注意什么时候是拷贝构造函数,在delphi中类对象是用指针传递的而其它类型是值传递,和java的用法相同哟!)

 

赋值对象:

Var

NewItem:TObject;

Begin

       NewItem:=TObject.Create;

       TheItem:=NewItem;

End;

 

以上不是一个好方法TheItem地址被NewItem代替,而不是值上的拷贝,会造成内在泄漏.可以用如下的方法解决:

Begin

       TheItem.Free;

       TheItem:=NewItem.Create;

End;

要记住重要的是,当将一个对象赋给另一个对象时,Delphi会将内在中对该对象的引用复制给新的对象引用.

注意对象是被引用所传递不需要使用var关键字,并且不需要任何其他明显的passby-reference语义指示.如果只想改变对象内的数据那就只能一个一个的处理了,在vcl中有一些类拥有Assign对象方法(好像c++拷贝构造函数的处理),它可以执行这种复制操作.更准确地讲,大多数继承自TPersistent, 而并非继承自TComponentVCL类都拥有Assign对象方法.

 

对象与内存:

至少,在没有Access Violations和消耗不需要的内在的情况下,如果我们允许系统协调工作的话,Delphi中的内在管理须遵循三条规则:

1.       每个对象在其可以使用这前必须被创建.

2.       每个对象在其使用之后必须被释放

3.       每个对象必须只能被释放一次.

 

 

注意:

1.调用Free来解除对象,而不发调用Destroy析构器.

2.使用FreeAndNil,或在调用Free后将对象引用设置为nil

3.可以通过Assigned函数来检查一个对象是否为nil.下列两条语句在大多数情况下都是相同的:

If Assigned(AData) then

If AData<>nil then

 

四.继承已有类型:

保护字段与封装:(Protected)

继承下来的字段可以直接在子类中访问但是不能在子类外访问

该方法违背了类保护机制,可能会在程序中引起错误,并且它也与优秀的OOP技术背道而驰.

 

继承与类型的兼容性:

       Pascal是一种具有严格类型定义的语言.子类赋值给父类是合法的,父类赋值给子类是非法的(但是也可以,只是不安全在特别处理一下)

 

滞后绑定与多态性:

       Pascal函数和过程通常基于静态绑定和超前绑定.即由编译器或连接器来解析对象方法的调用.滞后绑定与多态只在运行时才能确定所调用对象方法的实际地址.

 

主要是用virtual在父类中声明,用override在子类函数中调用覆盖

 

覆盖,重载:

覆盖:只有在父类中将方法定义为虚拟(或动态)后,才能进行覆盖.否则,如果是一个静态类型的对象方法,就没有办法激活滞后绑定,而只有改变其父类的代码.覆盖一个虚拟方法,必须指定相同的参数并使用关键字override.

重载:相同方法名不同的参数个数和类型overload

 

要在子类中使用父类的方法可以使用inherited关键字调用父类相同的方法来完成.

 

虚拟方法与动态方法:

       Delphi中,启动滞后绑定有两种基本办法:声明它为虚拟方法virtual,或声明它为动态方法dynamic,这两个关键字的语法相同,而且其结果也相同.差别在于,编译器用来实现滞后绑定的内部机制不同.

 

消息处理:

Procedure WMUser (var Msg: TMessage); message wm_User;

在这里message是关键字表示要处理器wm_User的消息.

可以用PostMessage(Form1.Handle, wm_User, 0, 0);来产生消息.

 

 

抽象方法:

       相当与C++的纯虚函数,关键字abstract用于声明只在当前类的子娄中定义的对象方法.含有abstract的类不能被实例化使用其函数.

 

类型安全的转换:

       这是C++不同版本是否支持RTTI技术来决定的在Delphi中使用和c++是一样的,利用子类是可以了解到自己的父类这一原则来处理,可以使用:

 

If MyAnimal is TDog then   //X0 is X1 或 TDog.IsHefitsFrom(MyAnimal)

//MyAnimal as TDog;相当与C中的强制转换或C++中的dynamic_cast<>

MyDog:=TDog(MyAnimal); 

Text : = MyDog.Eat;

 

使用接口:

       当定义一个抽象类来表示带层次结构的基类时,会发现抽象类是如此抽象,以至于它只列出了一系列虚拟函数,而没有提供任何实际的实现代码.

接口不是类,因为它们被看作是完全独立的元素,具有与从不同的特性:

1.       接口类型对象是引用计数的,当对象不再有引用 时会被自动销毁

2.       一个类可以继承自一个基类,但它还可以实现多个接口.

3.       因为所有类都派生自Tobject,所有接口都派生自IInterface, 故形成一个总的独立层次.

 

这里是一上接口声明的语法:(按照惯例,用字母I开头)

Type

       ICanFly = Interface

[‘{EAD9C4B4-ELC5-4CF4-9FA0-3B812C880A21}’]

Function Fly:string;

End;

(这个接口含有一个GUID,这是一个数字ID,后面跟随着它的声明并基于windows约定,可以在Delphi编辑器中使用Ctrl+shif+G组合键生成这个些标识符.)

为什么加入GUID

尽管可以在不指定GUID的情况下编译并使用接口,但通常还是应该为它们指定GUID,因为不这样的话,就需要使用该接口类型执行QueryInterface或动态的as类型转换,因为接口就是为了在运行时利用率扩展类型的灵活性,如果与类的类型比较的话,则没有GUID的接口就没有太大的用处.

Type

       TAirPlane = class(TInterfacedObject, ICanFly)

              Function Fly:string

       End;s

 

Var

       Flyer1:ICanFly;

Begin

       Flyer1:= TAirplane.Create;

       Flyer1.Fly;

End;

       无论使用直接赋值还是as语句,Delphi都将调用对象的_AddRef方法(IInterface定义).这种方法的标准实现就像TInterfaceObject提供的那个一样,用于增加对象的引用次数.同时,只要Flyer1变量走出范围时,Delphi就会调用_Release对象方法来减小引用次数.

       Delphi中,接口变量引用的对象是作引用计数的,并且当不再有接口变量引用它们时,它们便自动被释放.

 

 

异常处理:

Try:定义代码保护块的起始

Except:定义代码保护块的结尾,并引入异常处理语句.

Finally:用于指定必须执行的代码块,即使当异常出现时,这个块通常被用来执行总是需要的清除操作,如关闭文件或数据库表格,释放对象并释放在相同程序块中所要求的内存和其他资源.

 

类引用:

       它暗示代码是对类本身,不是类实例,进行处理.第一点需要注意的是,类的引用不是一个对象,它只是对类的类型的引用.一个类的引用类型确定了一个类引用变量类型.

用法:

Type

       TMyClassRef = class of TMyClass;

…..

Var

       AnObject:TMyClass;

       AClassRef:TMyClassRef;

Begin

       AnObject:=TMyClass.Create; //引用一个对象

       AClassRef:=TMyClass;                //引用一个类类型

作用:类的引用允许用户在运行时处理类数据类型.用户可以在数据类型使用合法的任何表达式中使用类的引用.

类的引用个人觉得主要是用在对控制的控制.

 

以上是本人从操delphi的新的开始,这些是以前的积累!既然是object pascal就要好好的学习OOP!终于补完了delphi的基本知识!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值