Delphi面向对象编程读书笔记_第1页
Delphi面向对象编程读书笔记_第2页
Delphi面向对象编程读书笔记_第3页
Delphi面向对象编程读书笔记_第4页
Delphi面向对象编程读书笔记_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Delphi面向对象编程读书笔记读书笔记之一Delphi中类的声明语法如下:type类名=class(基类名)数据成员声明过程和函数声明属性声明end;Example:typeTMan=classprivateFAge:Integer;procedureSetAge(Value:Integer);publicLanguage:string;Married:Boolean;Name:string;SkinColor:string;constructorCreate;overload;classprocedureSing;/唱国歌propertyAge:IntegerreadFAgewriteSe

2、tAge;procedureSayHello(words:string);end;对象构建Delphi中的类默认都是从TObject类继承而来,对象的创建必须调用构造函数Delphi中的对象分配存储空间都是在堆上,这点和C+不同,C+是可以在栈上分配对象的Example:procedureTForm1.Button1Click(Sender:TObject);varAPerson:TMan;beginAPerson:=TMan.Create;end;为什么可以采用TMan.Create这种形式来调用Create方法呢,因为Create前面有constructor关键字constructor相当

3、于将Create声明为Class方法相当于C+中static方法刘老师在书上的解释如下原话如下啊:注意这里的调用构造函数的语法有点特殊,是通过类型来引用一个对象的Create方法,而不是象其他方法那样通过实例来应用这看上去很奇怪,但很有意义,变量APerson在调用时还没有定义而类TMan已经静态地存在于内存中,静态方法调用它的Create方法是合法的而类TMyObject已经静态地存在于内存中我本人对这句话有点疑惑,类是不占存储空间的,怎么可以说类TMyObject已经静态地存在于内存中呢?我将在后面给出我的想法,暂时就到此关于is与as这两个都是运行期判别对象所属类型的操作符两则的用法的语

4、法上相似:对象变量is/as类名给出书上的例子说明问题procedureTForm1.ListBox1DragDrop(sender,source:TObject;x,y:Integer)beginifSourceisTEditthenListBox1.Items.Add(SourceasTEdit).Text);end;关于self在普通方法中self变量的值是对象的应用而在类方法中,self变量的值是类引用Example:TMan=classprivateFAge:Integer;procedureSetAge(Value:Integer);publicLanguage:string;Ma

5、rried:Boolean;Name:string;SkinColor:string;constructorCreate;overload;classprocedureSing;/唱国歌procedureSayHello(words:string);/打招呼propertyAge:IntegerreadFAgewriteSetAge;end;constructorTMan.Create;begininherited;Language:=中文;end;procedureTMan.SayHello(words:string);beginShowMessage(self.Name+words);en

6、d;procedureTMan.SetAge(Value:Integer);beginFAge:=Value;end;classprocedureTMan.Sing;beginShowMessage(self.ClassName+以勇军进行曲);/注意此处的self就是TMan显示TMan以勇军进行曲;end;procedureTForm1.Button1Click(Sender:TObject);varAPerson:TMan;beginTMan.Sing;APerson:=TMan.Create;APerson.Name:=小李;APerson.SayHello(是一名中国人);end;方

7、法的分类按用途分普通方法,构造方法,析构方法,类方法,消息处理方法按运行绑定机制分:静态方法,虚方法,动态方法,注意此处的静态方法不是所谓的lassmethod而是普通的方法,静态是指静态编译关于析构方法,最好是用名字destroy,这样可以使用Free方法,而不要直接调用destroy方法.Free方法会先判断对象变量是否为cedureTObject.Free;beginifSelfnilthenDestroy;end;消息处理方法的例子:procedureWMChar(varmessage:TWMChar);messageWM_CHAR;问题来了为什么在一个Control中声

8、明了消息处理方法,就能调用此消息处理方法呢这里涉及到TObject中Dispatch方法的秘密,我暂时没有看懂留作以后继续学习先给出Dispatch的源码.procedureTObject.Dispatch(varMessage);asmPUSHESIMOVSI,EDXORSI,SIJEdefaultCMPSI,0C000HJAEdefaultPUSHEAXMOVEAX,EAXCALLGetDynaMethodPOPEAXJEdefaultMOVECX,ESIPOPESIJMPECXdefault:POPESIMOVECX,EAXJMPDWORDPTRECX+VMTOFFSETTObject.

9、DefaultHandlerend;GetDynaMethod的方法源码如下procedureGetDynaMethod;asm-EAXvmtofclassSIdynamicmethodindex-ESIpointertoroutineZF=0iffoundtrashes:EAX,ECXPUSHEDIXCHGEAX,ESIJMPhaveVMTouterLoop:MOVESI,ESIhaveVMT:MOVEDI,ESI.vmtDynamicTableTESTEDI,EDIJEparentMOVZXECX,wordptrEDIPUSHECXADDEDI,2REPNESCASWJEfoundPOPE

10、CXparent:MOVESI,ESI.vmtParentTESTESI,ESIJNEouterLoopJMPexitfound:POPEAXADDEAX,EAXSUBEAX,ECXthiswillalwayscleartheZ-flag!MOVESI,EDI+EAX*2-4exit:POPEDIend;方法的覆盖,隐藏和重载覆盖是override,重载是overload;隐藏是子类中的方法和父类的方法同名,而且参数相同,没有override修饰符,则子类的方法就隐藏父类的方法.Example:TChineseMan=class(TMan)procedureSayHello(words:str

11、ing);/打招呼end;procedureTChineseMan.SayHello(words:string);beginShowMessage(TChineseManSayHello+words);end;procedureTForm1.Button1Click(Sender:TObject);varAPerson:TMan;AChinesePerson:TChinesePerson;beginAPerson:=TChineseMan.Create;APerson.SayHello(是一名中国人);/注意了此处调用的是父类的TMan.Sayhello方法/ChinesePerson:=TC

12、hinesePerson.Create;ChinesePerson.SayHello(是一名中国人);此时调用的是TChineseMan.sayHello/如果想要APerson调用TChineseMan.sayHello方法应该采取强制类型转换,强制类型转换其实就是对象框架的范围调整TChinesePerson(APerson).SayHello(是一名中国人);此时调用的是TChineseMan.sayHelloend;可见性Delphi中四种类成员的保护方式:published,public,protected,private;published,public是可以最大访问,protec

13、ted是对之类是可见的,private是对子类不可见另外对象变量如果与其类的声明在同一个单元中,则private,protected失去作用,全部都是public有点类似C+中友元的概念Example类TMan和此函数在同一个单元procedureTForm1.Button1Click(Sender:TObject);varAPerson:TMan;beginTMan.Sing;APerson.FAge:=10;虽然FAge是private,但是此处确可以访问APerson:=TMan.Create;APerson.Name:=小李;APerson.SayHello(是一名中国人);end;读

14、书笔记之二什么是对象对象是一组相关代码和数据的组合.面向对象程序设计中,过程(函数)被成为方法,数据被称做属性(注意此处的属性和类中property不是一回事)对象之间可以通过发送消息请求而互相联系,一个消息通常由三部分组成:接收对象的名字,对象成员的名字(方法和property),对象成员的参数对象是有类型的,不同的对象是属于不同的类型.对象的存储Delphi中的对象全是在堆上分配存储空间的.比如有一个APerson:TMan.APerson:=TMan.Create;这个时候会在程序的运行堆上分配TMan大小的存储空间,这个存储空间的大小可以用InstanceSize方法获得而APerso

15、n只是引用了这个对象,所以APerson是对象的引用.可想而知那么手工在堆上分配的对象,应该是要手工释放的Example:functiontest():TMan;varAPerson:TMan;beginAPerson:=TMan.Create;result:=APerson;注意这种方式APerson引用的对象是不会随着test方法的结束而结束的.结束的只是对象的引用APerson.对象依然存在end;对象在内存中的布局AOjbect-Vmt指针vmt表AObject.字段1AObject.字段2知道这个内存布局以后,就可以直接利用指针来访问对象中的成员了举个例子为了避免友元的影响,在Uni

16、t2中定义一个TMan类Unit2TMan=classprivateFWeight:Integer;FHeight:Integer;publicFName:string;FAge:integer;propertyWeight:IntegerreadFWeightwriteFWeight;end;在Unit1中使用TMan类Unit1usesUint2procedureTForm1.Button1Click(Sender:TObject);varAMan:TMan;Ptemp:PInteger;beginAMan:=TMan.Create;AMan.Weight:=100;Ptemp:=PInt

17、eger(AMan);PTemp:=PInteger(PTempT;Inc(PTemp);Edit1.Text:=IntToHex(Integer(PTemp),8);显示私有域中FWeight的地址Edit2.Text:=IntTostr(PTempT;显示FWeight的值end;因为FWeight是私有成员,按照规则是不能直接访问的但是通过地址的方法,我们绕开了这个限制,所以指针强大的功能在这里体现出来了对象引用和类引用对象引用上面的APerson已经给出了说明.类引用这个是概念是说能够声明一个类的类,看下面的例子TClass=classofTObject这个时候TClass就是TObj

18、ect类的类了声明一个TClass对象后varMyClassObject:TClass;则可以用MyClassObject来创建TObject对象varMyObject:TObject;MyObject:=MyClassObject.Create;另外书上的那段摘自倒是说的很经典回答了类到底是什么.我在笔记一中说类不占存储空间那是说类中的数据成员不会占为类分配的存储空,因间为数据成员是属于某一个具体的对象的数据成员只能存在对象的存储空间中,那么类中存了什么呢,答案是VMT表.所以类引用就是指向VMT表的指针(当然它不是以指针的语法形式给出的,可以把它理解为指针,实际上是引用)好了问题出现了,那

19、么普通的方法(非虚方法)到底是存在什么地方呢?对于普通的方法,编译器处理的时候是按面向过程的语言来处理的,也就是说,所有的类的普通方法都是一起存储在程序的代码段,只是在编译的时候,编译器自动为每个类中的普通方法添加一个隐含的参数self编译的时候,凡是程序中对类中普通的方法的调用,都已经用相对地址的形式直接给出这些普通方法的地址(这就是所谓的静态绑定)对于class方法,编译器在编译的时候隐含的参数self是指向类(也就是vmt表).普通方法中的self是指向对象本身的,注意二者的区别另外也可以将class方法声明称虚方法,那它就同时具备虚方法和class方法的特性.不过将class方法声明成

20、虚方法没有什么实用性因为class方法中不能使用数据成员.虚的好处也就体现不出来了对象的克隆以例子来说明:vara,b:TMyObject;begina:=TMyObject.create;b:=a;end;上述的代码说明了a与b同时指向一个实体对象,所以当利用a来改变对象的属性时,b也能感觉到.如果要让b引用的对象与a的不同,但二者友必须有相同的属性,这个时候就要用克隆的方法vara,b:TMyObject;/TMyObject是TPersistent的派生类begina:=TMyObject.create;b:=TMyObject.create;b.assign(a);/对象b的属性和内容

21、和对象a完全相同end;来看看TPersistent的源码:TPersistent=class(TObject)privateprocedureAssignError(Source:TPersistent);protectedprocedureAssignTo(Dest:TPersistent);virtual;procedureDefineProperties(Filer:TFiler);virtual;functionGetOwner:TPersistent;dynamic;publicdestructorDestroy;override;procedureAssign(Source:TP

22、ersistent);virtual;functionGetNamePath:string;dynamic;end;procedureTPersistent.Assign(Source:TPersistent);beginifSourcenilthenSource.AssignTo(Self)elseAssignError(nil);end;procedureTPersistent.AssignTo(Dest:TPersistent);beginDest.AssignError(Self);end;procedureTPersistent.AssignError(Source:TPersist

23、ent);varSourceName:string;beginifSourcenilthenSourceName:=Source.ClassNameelseSourceName:=nil;raiseEConvertError.CreateResFmt(SAssignError,SourceName,ClassName);end;Assign和AssignTo都是虚方法Assign是调用AssignTo方法,而AssignTo方法调用AssignError这里AssignError是个静态方法,最后只是引发一个异常而已.所以当自己创建的类直接从TPersistent类继承下来,应该重写Assig

24、n方法.对象的生死当一个对象实例用构造函数创建时,编译器将自动对对象的每一个域进行初时化,所有数字被赋值为0,所有指针为nil,所有字符串为空,Variant类型为Unassinged宏观上讲,对象创建实际上是经历了以下过程的为对象分配存储空间初时化对象中数据域3进入用户的Create函数,执行Create函数中的代码4.返回新建对象的一个引用这里书上提到了VCL类的组织形式:owner机制同时说出了两中设计模式composite和observer模式.我没有读过设计模式的书.但是这种设计思想还是让我受益的这个好比一个公司的管理结构,是有行政上的级别的.公司要执行某项决策时,命令是从董事会开始

25、下达,从董事会传达个各个分公司,再有各个分公司的总经理向各自的部门经理传达直到到公司的最底层的员工.动态生成对象这是本章中最闪光的一节,读起来很有启发.其中涉及到了工厂模式.动态对象生成要用到类的类概念,也就是类引用这里给出FactoryMethod模式下改进的动态控件创建的代码片段:TControlFactory=classprivateFControlObj:TControl;publicconstructorcreate(AOwner:TWinControl;ControlClass:TControlClass);end;constructorTControlFactory.create

26、(AOwner:TWinControl;ControlClass:TControlClass);beginFControlObj:=ControlClass.create(AOwner);FControlObj.Parent:=AOwner;FControlObj.Name:=FControlObj.ClassName;FControlObj.SetBounds(10,10,250,150);self:=TControlFactory(FControlObj);/这种转型值得学习.end;对于上面的那条转型语句,有必要要说一下,转型的本质是调整对象的执行框架.那么这样TControlFacto

27、ry(FControlObj)转型的时候,是调整FControlObj的执行框架,让它和TControlFactory的执行框架相同正因为TControlFactory中只声明一个成员FControlObj.这样二者的执行框架才能相同,所以才能转型成功.这段代码实则已经涉及到了对象在存储空间的如何存储的问题了.书上提到了TControlFactory自身实例无法销毁.那是因为self本来指向TControlFactroy对象实例,但是因为self:=TControlFactory(FControlObj);使得self已经不再指向TControlFactroy对象实例,这样就造成了内存泄漏对象

28、的生命期刘老师在书上的给出了两条关于组件对象生命期管理中肯的建议,A.创建有属主的组件不需要手工销毁B创建组件时指定属主在效率上不划算关于TCompont对象内存泄漏的问题,留给接口那章再来细读对象之间的关系对象之间的关系分为三类:泛化关系:表现对象的父子继承关系合成关系:细分为聚合和组合关系,表现对象的部分和整体关系C协作关系:细分为依赖和合作关系,表现为对象的互作用的特性泛化关系相对来说要好理解一些,表现在继承上合成关系中的聚合和组合是有区别的.组合是要求部分是整体的不可缺少的,并且只能为该整体对象占有,整体对象负责部分对象的生死聚合关系中对象之间的关联要比组合关系弱,部分对象不是整体对象

29、所专有的.该部分对象可以为其他对象所共享.书上的最后一个例子说明了所有的关系.还是给出代码才能说明问题unitDemo;interfaceusesSysUtils,Windows,Messages,Classes,Graphics,Controls,Forms,Dialogs;typeTGPSReceiver=class(TObject)publicprocedureNavigate;end;TEngine=class(TObject)privateFCapacity:Integer;FPower:Integer;publicprocedurestart;procedurestop;end;T

30、Wheel=class(TObject)privateFNo:Integer;FSize:Integer;FTypeName:string;procedurecheck;publicconstructorcreate(size:Integer;TypeName:string;No:Integer);end;TVehicle=class(TObject)protectedFColor:string;FMake:string;FTopSpeed:Integer;FWheel:TWheel;FWheels:TList;procedureSlowDown;procedureSpeedUp;proced

31、ureStart;procedureStop;end;TBicycle=class(TVehicle)publicconstructorcreate;destructorDestory;procedureride;end;TCar=class(TVehicle)privateFGPSReceiver:TGPSReceiver;FTopSpeed:Integer;protectedFEngine:TEngine;/FEngine和TCar的对象是组合关系.TCar对象负责FEngine对象的生死publicconstructorcreate(GPS:TGPSReceiver;color:string;Make:string;TopSpeed:Integer);destructorDestory;proceduredrive;propertyGPSReceiver:TGPSReceiverreadFGPSReceiverwriteFGPSReceiver;propertyTopSpeed:IntegerreadFTopSpeedwriteFTopSpeed;end;TPerson=class(TObject)publicprocedureDrive(car:TCar);procedureRide(Bicycle:TBicy

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论