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关键字中进行声明.
通常可以向一个属性赋予一个值或读取它,甚至在表达式中使用属性,但是不能将属性作为参数传递给过程和对象方法,这是因为属性不是一个内在位置,所以它不能被用做var或out参数,也不能通过引用传递.
构造器(constructor Create):
在构造器前面就使用constructor关键字.尽管可以为一个构造器使用任何名称,但还是应该坚持使用标准名称,Create.
通过使用一些参数定义Create构造器,可以用新定义代替默认定义并强制使用它.(可以定义多个构造函数)
析构器和Free方法:
在析构器前面使用destructor关键字.用标准名字Destory
Free释放对象,可以使用FreeAndNil(Obj)来完成Free和nil的过程
三.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, 而并非继承自TComponent的VCL类都拥有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的基本知识!