首页 Delphi培训课程

Delphi培训课程

举报
开通vip

Delphi培训课程 第 26 页 共 27 页 第一讲 delphi基础 【例】改变窗体的标题,颜色,尺寸   delphi 程序设计特点:可视化,开发方便 【例】写代码,改变标题,颜色,尺寸   对象成为处处用到的基本元素。对象含有属性和事件。delphi以pascal语法为基础。 一、delphi是什么? Delphi 是borland 公司研发的面向对象的,可视化的,快速的应用开发工具。   ◇对象是对相对独立的...

Delphi培训课程
第 26 页 共 27 页 第一讲 delphi基础 【例】改变窗体的标题,颜色,尺寸   delphi 程序设计特点:可视化,开发方便 【例】写代码,改变标题,颜色,尺寸   对象成为处处用到的基本元素。对象含有属性和事件。delphi以pascal语法为基础。 一、delphi是什么? Delphi 是borland 公司研发的面向对象的,可视化的,快速的应用开发工具。   ◇对象是对相对独立的客观存在或相对独立的逻辑存在的计算机 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 示。   ◇面向对象是与面向过程相比较而言的。 1 对象的三个主要特征:封装、继承和多态。 面向对象的优点:易管理,可重用。 2 可视化的体现: 所见即所得的界面设计;delphi组件是可视化的对象。 3 快速的原因: 可视化;丰富的函数,类库,组件,数据库组件;开发工具和向导;编译速度最快,语法的高度最一致。 二、delphi不是什么? 1 不是专门的数据库开发工具。 ◇研发的的背景和目的:windows初步流行,主要开发工具VC和VB各有所长;数据库开发的需求急剧增加。Delphi = VC功能+VB界面+快速数据库开发。 ◇delphi中没有专门为数据库操作保留的关键字。 ◇有很强数据库能力的原因是使用Delphi后续开发的数据库组件。  【图解】delphi语言及开发包提供的资源的关系。delphi的语言基础是object pascal,在其上构建的函数库,类库,控件库,甚至是IDE本身都不是语言的固有组成部分,而是用delphi语言写成的第一批工具,这扩展了delphi的能力,也验证了delphi的强大功能。 2 不是专门的界面开发工具。IDE本身是delphi程序且提供源代码;delphi可脱离IDE环境 而独立运行。   3 Delphi 可用于各种通用目的。通信,图形处理,数值计算,自动控制等。 三、学习基本语法前的准备   【例】不使用IDE的控制台小程序   program p; {$A ppt 关于艾滋病ppt课件精益管理ppt下载地图下载ppt可编辑假如ppt教学课件下载triz基础知识ppt ype console} begin writeln('hello'); end. 编译方法: DCC32 *.pas ◇语句是程序的基本组成元素;语句间用分号分隔;delphi没有行的概念 【例】稍微扩展的控制台小程序   program p; {$AppType console} const s = 'hello'; var a,b,c : integer; function MyAdd(x,y: integer): integer; begin MyAdd := x*10 + y; end; begin a:=5; b:=6;c:=myadd(a,b); writeln(c); writeln(s); end. ◇函数是最常见的语法现象 ◇‘:=’表示赋值操作;‘=’功能之一是表示定义;与C语言的写法有区别 1 源程序与机器表示的映射关系   【图解】源程序被翻译成机器码后,原来的结构特征消失了。在机器表示中,只有一种结构,就是:数据+操作码。通常的编译,把内存分为三个部分来使用:静态空间,栈空间和堆空间。 ◇我们我讨论的内存是经过操作系统虚拟过的内存,称逻辑内存或虚拟内存,这是相对于硬件上提供的物理内存而言的。 ◇函数被广泛使用,并且可以嵌套。一般通过栈的方法来实现在不同的函数执行环境间切换。栈的操作有两个,压栈和弹出。函数携带的参数也是通过栈的形式来传递的。   ◇栈也用来实现局部变量的自动申请和释放。   【例】windows风格的程序例子。工程是管理者,也是pas格式的代码,只是扩展名不同。单元是最重要的被管理的元素。.pas扩展名,是 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 的源代码。 2 与Dos程序不同,windows下的程序不在是从主函数开始的“一根面条”,而是与消息相联系的若干可执行的部分。 【图解】在windows下,代码响应事件(或消息的过程)。消息是可以被传递的信息,有固定的格式,应用程序可以发送消息,也可以接受消息。   3 接受到的消息被放在队列中,等待处理。windows下的应用程序只做两个循环往复的动作:提取消息和处理消息。 ◇消息由标识和参数组成   ◇具有某个标识的消息可以和某个函数相关联,叫做:消息映射。   【例】怎样在windows下输出信息呢?在windows下,对屏幕的输出是输出图象,一般是通过画的方法,而不是写。屏幕被抽象为许多逻辑上独立的区域,供给多个程序使用。这些矩形区,叫窗口。程序中用于代表窗口的可输出能力的对象是TCanvas。   ◇可以通过canvas在自己的窗口上直接画图形,或“画字”   ◇可以控制canvas内的pen和brush等对象来实现对输出内容外观的控制。   【例】使用控件直接输出内容。这是实现输出的更常用的方法。也体现了对象的重用性的优点。 4 修改控件的属性,就可以直接实现输出。这与VC不同,改变属性,不是简单地改变了对应单元的数值,而是执行得了更复杂的操作,否则无法实现屏幕内容的变化。   ◇在屏幕上看到的控件也是窗口。我们所节省的代码在编写这些控件的代码中必须出现,而且,也是通过canvas向屏幕输出的。   ◇使用控件的优点是简单,直观。控件可在设计时修改属性。   【例】保存工程,指定目录和修改名字 5 在我们指定的目录中,有许多文件,他们的关系如图。.dcu和.exe较大,我们拷贝源程序的一般方法是删除.dcu和.exe其他的都拷贝。 ◇重要原则:不要去删除自动生成的代码。我们把自己写的删除,IDE会自动把它写的删除。   ◇不可用save as 的方法备份源程序,这样会使工程中的单元的路径改变。 6 获得帮助的办法是把光标停在某词上按F1,这时会出现与该词相关的帮助。   四、基础语法   1 不可忽视注释。文档是软件的重要组成部分。delphi的注释有多种方法:{}用于注释一段文字;//表示行注释;{}也可以注释一段。{$..} 是特例,表示编译指令。   2 有名量和匿名量。名字是量的标识符,是用于区分不同的量的手段。   ◇标识符的定义规则是:字母开头;不含空格;最长255;一般只含字母,数字,下划线。   ◇名字要有意义,不要用拼音缩写。可以用英语或全拼。GZ:工资?高中?规则?广州?   ◇delphi不区分大小写,可以用字头大写或下划线区分名字中不同的字。如:gong_zi;GongZi; DaYin_BaoBiao;CaiDan_BaoCun_WenJian;Menu_SaveFile。   3 常量和变量。通过前缀修饰符const,var定义常量和变量。   ◇var和const不是域的概念,只是前缀。之所以看起来象域定义,是因为如果省略前缀就默认为与前一条语句的前缀相同。 ◇普通常量不分配内存地址,表现为代码中的立即数。 ◇类型常量分配内存,有地址,可以通过指针使用它。 4 数据类型综述。 ◇学习数据类型时要弄清楚的问题:用处?定义?占多少内存?常量怎样表示?有关的函数? ◇数据类型可从多个角度划分。我们从使用该类型的角度看,可划分为书中p20的结构。若从是否需要定义的角度看,可分为原始类型和用户定义类型。 ◇要注意各个类型间是否可转换及如何实现转换。比如整数和实数。 5 整数 ◇用处:表达可数的数目;记录循环次数 ◇定义:var a: integer; b,c: int64; ◇内存占用:见p21 ◇常量表示:普通 123;十六进制 $1FE7; ◇必会函数:Div, Mod, Dec, Inc, StrToInt, 6 字符 ◇用处:表示单个字母或数字 ◇定义:var a: char; const b:char='x'; ◇内存占用:P23 ◇常量表示:'a';单引号本身的表示:'''';chr(39);#39; ◇必会函数:chr, ord 7 布尔 ◇用处:表示是或不是 ◇定义:var a: boolean; ◇内存占用:P24 ◇常量表示:true,false ◇必会函数:not and or 8 枚举 ◇用处:代表有限集合中的每一个元素,为每个元素指定一个有意义的名字。 ◇定义:type TV_Color = (TV_red, TV_Blue, TV_Green); var a: TV_Color; ◇内存占用:相当于常量,无内存地址 ◇常量表示:TV_red, TV_Blue。 ◇必会函数:ord取得序号;序号从零开始。 9 子域 ◇用处:限定范围的字符类型或整型(序数类型),可在编译阶段检查赋值合法性。 ◇定义:type Age=1..200;var a: Age; ◇内存占用:与它使用的序数类型相同。 10 实数 ◇用处:表示连续量 ◇定义:var x,y: double; ◇内存占用:见p26 ◇常量表示:34.56;0.23;.23;1.2E-3; ◇必会函数:FloatToStr,FormatFloat,Int,Frac,Round 11 记录 ◇用处:把许多量组合在一个类型中 ◇定义:type STU=record name: string[10]; id:integer; age: double; end; var a: STU; ◇内存占用:基本上等于组成的变量所占内存的和(存在整字对齐问题) ◇引用:edit1.text := a.name; a.age := 15.5; ◇注意:元素可以是任何类型,甚至是另一个记录类型;可以用packed指定不要整字对齐。 12 数组 ◇用处:表示同型元素构成的列表 ◇定义:type AAA = array[0..100] of char; BBB=array[5..10] of STU; var a: AAA; ◇内存占用:数组大小乘单个元素的占用。 ◇引用:a[下标];如 a[2], a[34] ◇必会函数:Low,High。 13 字符串 delphi中最重要的数据类型 ◇delphi的串不是定义类型,是语言固有的类型,这与C串的概念不同。 ◇delphi的串有短串和长串之分。一般短串在栈中分配空间,长串在堆中分配空间。短串最大长度是255,与C的串占用空间相同,结构有区别。在堆上分配的长串,是自动堆对象,不需要手动地申请和释放。 ◇定义:var s: string; {长串}  s2: string[12]; {短串} ◇可以用下标的方法引用串中的单个字母:s := 'hello'; 则 s[1] 表示‘h’, s[3] 表示‘l’。 ◇必会的内部函数:length(s);s1:=copy(s,1,2);delete(s,3,2);insert('abc',s,2); i := Pos('abc',s); s:=LowerCase(s); upperCase; format。 14 语句综述   与其他的语言的语句形似,delphi的语句从流程方向上也分三种:顺序语句,选择语句,循环语句。从语法结构上又分为单语句和复合句。复合语句是由begin,end 包含一组语句。类似C语言的{ }。语句间的分隔符是分号。   15 选择结构   if 语句的格式: ①if .. then ..; ②if .. then .. else .. ;   ◇if x = 5 then x := x + 5;else x := 12; 是错误的写法   ◇if x > 90 then t:=1 else if x >80 then t:=2 else if x > 70 then t:=3 else t:=4;是正确的写法。注意elseif 不能连写。   【技巧】 减少嵌套层数的技巧 逐渐逼近条件法   case 语句的格式:case x of 1:t:=1;2: t:=2;3..7: t:=3;else t:=4 end;   ◇case s of 'abc': t:=1;'bcd': t:=2 .... 是错误的写法。case 只能是序数类型。   ◇case x of 1: t1:=2;t2:=3;2: t1:=4;t2:=5;end;是错误的。分支情况后边只能是一条语句,如果有多条语句,要使用复合语句来处理。 16 循环结构 for .. do ..; while .. do ..; repeat .. until ..; 一般for适用于次数可确定的循环;while先判断条件,repeat 先执行。 break 用于从循环中跳出; continue用于跳过一次循环,执行下一次。   17 其他较深的语法在后边分别介绍。包括多维数组,动态数组,集合,函数的参数传递方式,指针,函数指针,类引用,文件类型,变体类型,变体数组等。 第二讲 面向对象的程序设计   构成delphi的语言基础,严格地说,不是pascal而是object pascal;后者不是对前者的简单扩充和升级,而是思想上,结构上的全面革新。贯穿object pascal始终的概念是对象。 一、面向对象的原理   ◇面向对象是与面向过程相比较而言的。面向过程的结构化设计方法被广泛使用,但在代码量增大时(1万行以上)有许多困难难以克服。比如全局变量不容易控制;重用性不好等。   ◇对象是对具有独立性质的事物的抽象。我们考察对象时,只关心对象的性质和行为,而不关心对象的内部实现机制。对象的最大优点是可重用性。   ◇对象间可以通过消息的传递来相互影响,协作完成某个特定的任务。   ◇与对象有关的三个概念:封装,继承与多态   1 封装不是简单地装起来,比如记录结构,比如子目录结构。封装的真正含义是隐藏,就是隐藏代表对象状态的内部数据。   ◇函数象一部加工机器,而对象保存自己的状态。对象不能用函数加全局变量实现。因为对象的数据是私有的,外界不能直接访问,并且多个同类型的对象可同时存在,且状态不同。   【模型】现实世界中的收音机。设计良好的收音机,外界的输入错误并不会破坏内部的元件。   2 封装的内容是私有的数据和操作。但如果私有的东西完全不能被访问则没有意义。不能被外界感知的东西对外界来说就是不存在的。所以要对外界提供访问接口:属性和方法。属性和方法是对被封装的内容的曲折的反映和间接的操纵。   3 定义对象的性质的程序文档,称为类。类并不存在于内存中。通过类可以生成或说制造出多个同属于一个类型的对象。这个过程称为实例化。   4 用于描述多种对象的文档可能有许多相似的地方。我们可以通过继承的方法减少这种重复描述的文档。继承就是指出某个文档包含其他文档中描述的特征。   ◇继承是文档的特征,因而只是对类而言的。对象是内存中实例,对对象而言,不存在继承的概念。当观察一个对象实例的时候,我们并不知道它是否是通过继承的方式被构造的。   ◇对从其他文档中继承的内容,我们可以通过重新描述而替代原来的内容,或者干脆通过隐藏的方法而不向外界公布某些内容。可见继承并不一定必须是上下级的关系。只要有相似的地方,就可以使用继承,继承的目的之一是为了省写代码,即代码重用。   ◇在定义类的时候,继承提供了极大的方便。这启发我们定义一些描述多种对象性质的抽象的类。这些类不能生成实例对象,它们的唯一作用就是为其他的类描述提供继承。   5 多态是面向对象的精髓。一般来说,多态指对同样的消息,不同的响应。静态多态通过函数重载来实现;狭义的多态指在编译时无法确定要调用的函数的地址的现象。   【模型】从劳动者类继承的农民,工人和其他劳动者,从农民类继承的青年农民中,有些定义了劳动这个动作。见图。 ◇形成多态的前提:抽象地看待一个对象。把农民,青年农民,工人都抽象地当作劳动者来处理。这种处理方法叫做泛化。 ◇在调用一个被泛化的对象的方法时,一般我们并不是希望调用抽象类的方法,而是希望执行对该对象而言,最具体的方法。因为在编译时无法确定被泛化的对象的真正类型,因而就无法确定要执行的函数的地址,从而产生多态的现象。 ◇多态的实施是通过在运行时保存类型信息的办法来实现的。类型信息是关于类的全体的公共信息,不是专属于某一个特定的对象。类型信息间有继承关系,就是对类的继承关系的计算机表示。 ◇多态的方法使我们站在概括的高度来处理对象,抽象思维是人类的特点和优点,多态的使用充分发挥了这种优势。我们在抽象设计的时候,可以把注意力放在对象间的本质联系上,可以不考虑任何具体特征,这种设计方法称为蓝图设计。 ◇继承的目的之二就是要产生多态的能力。这是继承的重要目标。 6 面向过程的设计方法=数据结构+算法;面向过程的设计方法=对象+消息 【模型】奴隶社会和现代社会的对比。在生产资料少之又少的时候,集中管理更有效,在生产极大发展的时候,分布式的对象模型更有潜力和稳定性。 ◇设计原则: ①对象要有独立的特点,就是不依赖或较少地依赖于外界。用术语表达,就是对象要有确定的边界。边界把对象的内部和外界环境严格地区分开。换句话说,我们必须能够明确地指出哪些属于对象,哪些不属于对象。 ②对象要能完成相对独立的功能。对象的定义一般从功能的定义入手。 ③对象要保护自己的数据,使外界无法干涉对象的独立性。同时,对象的方法应该操作自己的数据,而不是去他人的数据。 ④对象对外界的影响是通过向其他对象发送消息来实现的。尽量避免直接操作外部的数据结构。 7 面向对象的设计并不完全排斥面向过程结构化方法。体现在: ①一般大型工程项目都采用了自顶向下与自底向上相结合的方法。好比盖楼房。 ②在每个对象实现过程中仍然要使用结构化的设计方法。 8 构建类的时候,注意考虑对未来重用性能。尽量能构造成树型的类群,以便将来从合适的节点继承形成新类。 9 面向对象的思想的实现要兼顾到运行效率的问题。就效率而言: c++ > delhi > Java > smallTalk。就面向对象的彻底性而言,则刚好相反。 二、面向对象的delphi实现   1 类的定义  type 类名=class(父类) ... end;   ◇不写父类,表示从TObject 继承,这时,括号也不写   ◇不支持多重继承。可以通过支持接口的方法实现多重继承的类似功能。   2 保护方式  关键字 private protected public published   可以把类的用户分成三组:①自己:就是类的成员函数 ②子孙:就是从本类直接或间接继承的类的成员函数 ③他人:就是除此以外的其他函数。 private protected public Published 自己 允许 允许 允许 允许 子孙 禁止 允许 允许 允许 他人 禁止 禁止 允许 允许      ◇published与public有相同的保护效果。但publised修饰的成员可以在设计时出现在对象浏览器中。注意,这不是delphi的内部功能,因为对象浏览器也是用delphi写的。   ◇有一个特例:处于同一单元的定义,可以自由访问,忽略保护方式描述字   ◇保护方式也是一个前缀,不是域的概念,后边无冒号,注意与C的区别。   3 类操作符――is和as ①is的用法:表达式“对象is类”返回一个布尔类型。如,猫是猫类;猫是动物类。   ②as的用法:表达式“对象as类”返回该对象,但类型已经强制为后边的类所指定的类型。这种表达方法叫特化。   ③二者经常联合使用。if a is TA then (a as TA).caption := ... 【例】多个控件连接到同一个事件,怎样在事件中区分是哪个控件发出的事件?不同类型的判断要用is,相同类型的判断要用as配合tag属性。   4 对象存储结构   在内存中,只存储对象的私有数据,而方法只有一个拷贝,与其他函数一起存于静态空间。对象在定义的时候,只是一个指针(4字节)并无对象的实体。必须调用类的构造方法才能生成对象。该对象存于堆空间中。对象在使用完毕后,需要调用它的析构函数来完成对内存的释放。在delphi中,一般不直接调用析构函数,而是调用free函数,这是更安全的方法。   5 类引用   类引用是指向类的公共信息的类型。类引用包含了类的名字,父类引用,对象占用多少内存等信息。类引用的使用是为了在运行的时候,获得关于对象的类的特征的描述。   定义:type 标识符 = class of 类名;   ◇在早期的面向对象语言中无类型信息的概念。这些信息只有编译器知道,而无法被运行中的代码获得。运行时类型信息,就是资料中常提到的RTTI。   【例】取得对象的RTTI .instanceSize返回整数;.classparent返回父类型信息。   6 构造函数   构造函数是特殊的函数,严格地说它不是成员函数,构造函数完成内存申请和初始化成员变量的作用。构造顺序是先构造祖先,再构造自己。   ◇定义: constructor create;或 constructor create(参数列表);   ◇构造函数的实现中一般多要先调用祖先的构造函数。方法是:inherited create.. ◇定义两个构造函数时,要用overload关键字表示重载,这是静态多态的例子。 7 析构函数 析构函数是成员函数。析构函数是动态多态的典型例子。当一个对象被抽象地处理时,一定要调用属于这个对象的类所定义的析构函数。而不是抽象类的析构函数。析构的顺序是,先析构自己,再析构祖先,和构造正相反。 ◇定义:destructor destroy;override; ◇在实现的时候,不写override。这个关键字指示着该名字的函数在运行中要做动态多态处理。   ◇一般来说,析构函数的末尾总是调用祖先的析构函数。inherited;多态特征的函数不需要指明要调用的祖先函数名。   ◇与C++不同,delphi的构造函数和析构函数都不会被编译器自动调用,必须显式地调用。   8 替换与覆盖   替换是根据局部优先的原则,用同名的成员代替祖先定义的成员。这是为了屏蔽祖先定义的某个方法或数据。覆盖则是把祖先定义的方法具体化,或说特化。这是实现多态的基础。   实现覆盖的方法:①父类声明中加 virtual;②子类声明中加override;③子类实现中不加。 ◇用dynamic 和virtual 具有同样的逻辑含义,只是实现的方式不同。 ◇有时,覆盖的方法也称虚方法或动态方法。 9 抽象类型 只定义不实现的虚方法称抽象方法。至少含有一个抽象方法的类称为抽象类。抽象类型不能实例化,只能供给其他类做继承之用。 10 属性 属性就是对象的性质的外部表示或外部视图。属性的使用贯彻了面向对象中的封装的思想,是delphi与C++相区别的地方。理解了属性的概念,就理解了封装。 ◇定义:property 变量:类型;read 读方法 write 写方法; ◇这样的定义使外界看起来,好象该对象有一个成员变量。实际上,这个变量是虚拟的,在内存中并不存在,当涉及到它的读取时,实际上调用了读方法;当涉及到它的赋值时,实际上调用了写方法。 ◇属性就象对象的私有数据的一个影子。它提供了对私有数据的访问的同时提供了保护。   【例】 type TA=class   //类的定义开始 private fx: integer; // 私有数据 private function getx: integer;  //读方法 procedure setx(n: integer);  //写方法 published property x:integer; read getx write setx;  //属性的定义 end; //类的定义结束 var a: TA; .... a.x := 5;等价于 a.setx(5);   c:=a.x;等价于 c:=a.getx; ◇属性可以直接与私有变量关联。    published property x:integer; read fx write setx;  //属性的定义   ◇有read 无write 时,表明该属性是只读属性。   ◇所谓事件也是属性,只不过它的值是指针,是方法指针,指向用户定义的某个方法。 三、类开发方法提示   1  分析 定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析 需要的功能,从delphi类库中找到最合适的节点来继承。   2 可以从可视化的构件继承。不一定要注册,不注册的控件可以正常在程序中使用。   【例】自己定义一个中国Edit控件。特点是回车键当Tab键来使用。   type TMyEdit=class(TEdit) private procedure WndProc(var msg: TMessaeg); override; end; //类的定义部分。在其中覆盖了父类的虚拟方法 WndProc procedure TMyEdit.WndProc(var msg: TMessage); //实现的时候,不要写 override begin if (msg.msg = wm_keyDown) and (msg.wParam = vk_Return) then parent.perform(wm_nextDlgCtl,0,0) else inherited; end; //当按了回车键的时候,给父窗口发消息,移动焦点到下一个控件  3 类的生成还有一种方法,就是嵌入另一个控件作为自己的成员数据。用这种办法生成的类叫做包装类。使用包装类,一般是把被包装的控件当作工具来使用,而不是特化的过程。  【练习】包装一个时钟类,显示日期和时间。从TPanel继承,把TTimer作为成员数据 第三讲 编程进阶 【思考】假如我们要把一个地图数据装入数组,然后显示它,却不知道地图数据有多大,怎么办呢?开一个足够大的数组吗?windows的消息结构只能容纳8个字节,我怎么通过这么少的字节传递长达500k的数据呢? 一、语法进阶 1 动态数组。动态数组是指尺寸在运行时可以改变的数组。  定义:var a: array of integer;   //其中没有 说明 关于失联党员情况说明岗位说明总经理岗位说明书会计岗位说明书行政主管岗位说明书 尺寸    ◇动态数组在使用的时候,要先设定尺寸。setLength(a,20); ◇下标的引用从0开始。  ◇动态数组可以当作函数的参数来传递,这种参数称为开发数组参数。对开放数组参数赋给常量的时候,使用方括号。  【例】 使用开放数组求和   function MySum(a: array of integer): integer var i: integer; begin result := 0; for i:=low(a) to high(a) do result := result + a[i]; end; .... edit1.text := intToStr(MySum([1,2,3,4])); .... var s: array of integer; .... s[0]:=1; s[1]:=2; ..... edit1.text := intToStr(MySum(s)); 2 多维数组。多维数组只不过是关于数组的数组,就是说数组的元素仍然是另一个数组。  定义:type 类型标识: array [下标范围] of array [下标范围] of 某类型;  例如:type AAA: array [0..9] of array [5..10] of integer; 访问方法:var a: AAA; ... a[1][5] := 10;  ◇还有另一种定义和引用的方法,但不能体现多维数组的本质。   type AAA: array[0..9,5..10] of integer;... a[1,5]:=12;  3 函数,过程和参数  delphi中的子程序有函数和过程的区分。带有返回值的叫函数,没有返回值的叫过程。它们的定义采用了不同关键字,这是与C语言不同的地方。   定义:function 函数名(函数参数):返回值类型;      例如:function myAdd(x,y: integer): integer; procedure 过程名(过程参数);      例如:procedure MyProc(s: string); ◇当没有参数的时候,一对圆括号要省略。这与C不同。  ◇调用子程序的那个程序叫主调方;被调用的子程序叫被调方。主调方传入给子程序的作为子程序的参数的量称为实际参数,简称实参;在子程序中定义的参数,称为形式参数,简称形参。  ◇delphi中子程序的参数有两中传递方式:按数值传递和按地址传递。按数值传递就是把主调函数传入的值(即实参)拷贝一份给子程序。这样子程序对这个拷贝进行修改的时候不会影响实参。按地址传送,是把实参所在的内存的地址传给子程序,子程序通过地址对数据进行的修改实际上就是在修改实参的值。  ◇缺省的方式按值传递。  ◇要求传地址时,使用var修饰形参。  ◇有两个按地址传送的变种,限定了数值的传送方向。const 修饰的参数按地址传送,但在子程序中不能修改。out修饰的参数表明只是用于传送返回值的。 【例】 使用开放数组求和,通过参数返回和   procedure MySum(const a: array of integer; b: integer); var i: integer; begin b := 0; for i:=low(a) to high(a) do b := b + a[i]; end; ◇注意,这里的const并不是说要传入常量参数,而是说传入的数据不能被修改。   4 指针   ◇指针就是一个数值。这个数值是内存的地址标号。在该地址中存着某种类型的量。   定义:type 类型名=^类型名; 例子:type MP=^integer; //定义了指向整型量的指针。 使用:var p: MP; a: integer; ... p := @a; p^=5; ◇@是取得变量地址的操作。^在前定义指针;^在后取某个指针所指向的值。 运算:Inc(p);指针移动,使它指向下一个数据元素;Dec(p);指针向前移动。 ◇指针具有灵活性,常配合数组一起使用。 5 过程类型 一般来说,在编译后,子程序的地址都是一个固定的数字。但有时候我们需要浮动地调用同一类子程序中的某一个,这就需要一个指向子程序所在地址而不是变量所在地址的指针。在delphi中,把这种类型的变量独立出来,叫做过程类型。 定义: type 标识符 = function(参数):返回; 或 type标识符 = procedure(参数); //注意,这种定义,没有写子程序的名字 更常用的是,指向类的方法的指针。其定义类似: type标识符 = procedure(参数) of object; 【例】用程序的方法生成一个按钮,把这个按钮的点击事件连接到自己预先定义的成员方法中。 ◇方法指针不一定要指向自己定义的类中的方法。这种设计使得我们可以不生成新的类,就改变对象对事件的响应行为。 二、熟练使用代码编辑器 代码编辑器为我们提供了许多方便的功能,能够大大地提高我们的编程效率。许多功能都对应着快键的操作,通过熟练地使用键盘,可以事半功倍地完成许多常见的代码编辑任务。 1 追踪一个标识符的定义。鼠标右键|选find declaration 2 在当前工作的地方快速地设置或取消书签。 Ctrl + Shift + 数字 移动到某个书签。 Ctrl + 数字 3 选中某一个块。 shift + 方向键 4 把一个块向前移动或向后缩进。Ctrl + K,I; Ctrl + K,U 5 在函数的定义和实现间进行跳转。 Ctrl + Shift + 上下箭头 6 从摸板中粘帖代码。 Ctrl + J 7 向摸板中增加代码。 tools|editor options|code insight|add 8 代码补全功能。我们定义好了类的声明部分,如果语法正确,可以delphi替我们把实现部分的代码框架写好。 Ctrl + Shift + C 9 查看活动窗口列表。 Alt + 0 10 快速弹出对象监视器。 F11 11 在代码和窗体间切换。 F12 12 删除当前行。 Ctrl + Y 13 立即存盘。 Ctrl + S 14 程序复位。 Ctrl + F2 15 运行程序。 F9 16 恢复一步操作。 Ctrl + Z 三、TStrings对象 TStrnigs代表着字符串的列表,在delphi中有着十分广泛的用途。 1 TStrings是抽象类型的对象,不能生成实例。 2 我们经常用到的该类的派生是TMemo.lines属性。我们通过对Tmemo.lines的操作,就可以改变memo中的内容。 【例】用一个时钟触发事件,向memo1中添加数据。当memo1中字符串数量很多时,把第一行删除,如此往复。 memo1.lines.add(timeToStr(now)); if memo1.lines.count > 10 then memo1.lines.delete(0); ◇我们把第一行删除后,总的行数就减少了,并且其后的每一行的行号都发生了变化。 3 TStrings类的其它的常用方法。 .clear //清除字符串列表 .insert(位置,字符串) //在某位置插入一个串 .loadFromFile(文件名) //从文件中读入 .saveToFile(文件名) //向文件写出 【例】TMemo实现的简单的文本文件的编辑功能。 4 重要属性 .count //所包含的字符串的数目 .values[name串] //返回具有该name 的value串 ◇我们在写配置文件的时候,常常用到一种叫做键-值结构的表达方法,就是name=value的形式。例如:path=c:\gyhang\t1; sendname=PA。 ◇相关联的方法有:indexofName(name串) 返回该‘键’所在行号。 5 常用的不可见的字符串列表类型 TStringList ◇自定义的对象使用前一定要先创建该对象。使用后把它释放。 ◇TStringList除了具有TStrings属性外,还能自动排序。 【练习】使用TStringList制作小配置文件,读出一个键的值,改变它,并存盘 四、异常和保护 传统的程序员经常是花30%的精力来完成业务流程,却要花70%的精力去防止用户的误操作或处理其它的意外情况。delphi提供了异常和保护的方法,使程序员可以从更加概括的角度用更加灵活的手段来处理错误和保护系统的资源。 1 异常的使用 try 正常操作 except 错误处理 end; // try 和 except 是关键字,与end一起构成了一个结构,这个结构中两个块,就是try块和except块。在try块中发生的任何异常都会在except块中被捕获。 在except块中,可以对不同的异常种类去执行不同的操作 ◇在被捕获后,异常就消失了。如果捕获块认为自己没有完全处理好这个异常,需要外层继续处理,可以再次提起异常。方法是: except ... raise; end; ◇异常与if判断不同,它可以穿越所有的函数嵌套层次,直到被捕获为止。如果我们不定义捕获块,则delphi在最外层提供的缺剩捕获块会捕获它。这最后一关是:Application.onException,我们可以提供自己的方法来代替系统缺省动作,从而避免弹出难看的出错对话框。 ◇我们可以定义自己的异常类(从Exception派生),并可以在没有发生系统异常的情况下,主动提出异常。这时,可以把自己的异常对象发送出去。在自己的异常对象中可以携带大量的数据,这就比判断简单的返回值有更多的优越性。提出异常的语法是: raise 某个异常对象; ◇我们也可以使用哑异常,来终止一次执行过程,并不显示任何错误信息。 【比较】abort exit break terminate 2 保护的使用 申请资源;try 正常操作 finally 释放资源 end; 无论在try块中发生了什么事情,finally块中的代码都会被执行的。这避免使程序中忘记了释放资源,或多次释放同一资源。 ◇异常和保护经常被嵌套使用。 lst := TStringList.create; try try lst.loadFromFile('c:\a.txt'); ... except showMessage('文件不存在'); end; finally lst.free; end; ◇ 也可以把finally块放在里边。这时,如发生异常,会先执行了finally块,再跳到异常处理块。一般也提倡这种方法,就是,如果发生错误,尽量早地释放资源,以免夜长梦多。 try lst := TStringList.create; try lst.loadFromFile('c:\a.txt'); 其它操作; finally lst.free; end; except showMessage('文件不存在'); end; 第四讲 数据库编程(一) 一、基础补充 1 开域语句 在面向对象的程序代码中,嵌套对象的现象十分普遍,我们经常会去引用很深层的对象。如: form1.canvas.font。当对一个深层对象设多个属性的时候,要写很多重复的符号,麻烦且容易出错。为此,delphi设计了开域语句。 格式: width 对象 do ...; 一般情况下都是跟随多条语句,所有几乎总是用复合语句,即 width 对象 do begin ... end; 例如: with form1.canvas.font do begin color := clRed; size := 15; name:='宋体' end; 2 集合的使用 delphi中的集合是对数学中集合的概念的简单实现。要求是集合中的元素必须同类型,且必须是序数类型,且集合中可能的元素个数不能大于255。 定义: type 集合类型名 = set of 元素类型 例如: type MySet = set of char; //注意 char 的个数本来就不超过255。 type MyItem = (sun, moon, star); MyItem2 = 1..100; type MySet2 = set of MyItme; MySet3 = set of MyItem2; ◇我们可以测试给定的元素是否在某个集合中。 var A: MySet; 'a' in A ? ◇集合的常量表达法: ['a','x','c']; [1,2,4..10]; [sun, moon] ◇空集的表示法: [] ◇集合间可以直接赋值。 A := []; A := [1,2,6]; A := B; ◇集合间可以进行标准的运算: A+B 并集; A-B 差集; A*B 交集 我们经常使用集合来表达用户对多选控件的选择情况。因为delphi定义了标准的集合运算,就使得我们处理类似:“两个用户公共选择了哪些项?”“从选择中去掉固定的一组选则”这样问题变得十分简单容易。delphi的控件属性中,有很多的是集合类型的例子。比如 with form1.canvas.font do style := style + [fsItalic] 就是增加了斜体特征。 二、数据库的知识 1 数据库是按照一定的结构组织起来的数据。组织的目的是为了方便操作。操作包括查找,增添,修改,删除等。不同的组织方法形成了不同的数据库模型。流行最广的是关系模型。 2 关系模型中,数据库由二维表构成。它的行叫记录。列叫域或字段。关系模型的数学基础是集合论。严格地说,表是记录的集合。也就是说,不能有每个字段都相同的记录;仅仅是记录排列的位置不同的表被看做是相同的表。 3 常听说的E-R模型是实体-联系模型的缩写。它是关系型数据库设计的理想状态。就是说:一张表,要么表达的是实体,要么表达的是联系。我们在创建表的时候就首先要明确这个表的E-R属性。实体必须的要素是标识和属性。标识能把不同的实体分开,叫主键。联系的要素是被关联的实体和联系的属性。被关联的实体的标识联合决定了唯一的联系,可做主键。每一个实体标识代表了外部的一个实体,叫外键。 【比较】表的设计的例子。学生,课程,成绩。典型的实体关系模型。 药品出库表:药物号,药物名,单价,数量,出库量,库存剩余,出库日期,经办人,用途,发货单号,备注。是错误的方案。可以用词性分析的方法初步分析出实体和联系。一般名词表示实体,动词表示联系。 药品出库:o1 + v + o2。‘药品’和‘仓库’是两个实体,‘出’是联系。 4 完整性规则。实体完整性,参照完整性。 5 桌面库与大型库的区别。 ◇区别的标志是DBMS在哪台机器上执行,而不是操作台离数据库文件的远近。 ◇DBMS是管理数据关系的系统。 ◇C/S模型的优势是:减小了网络负担;支持并发访问。 ◇发展方向是B/S模型。就是浏览器做客户端的方式。 三、delphi的数据库访问原理 1 BDE是borland公司提供的数据库引擎。目的是为了实现不同数据库的统一访问方式。BDE中内置了本地的DBMS,支持dbase,paradox,foxpro的直接访问。 如图,BDE可以通过ODBC接口访问几乎所有数据库。另外,borland公司也提供了对大型数据库比如oracle,sybase,db2,sql-server等的SQL-Link连接访问方式。这中连接方式比ODBC速度快。 ◇使用SQL-Link仍然需要安装大型库的客户端程序。 ◇ADO是微软继ODBC之后推出的新的数据库访问标准,其技术基础是OLE DB,支持更丰富的数据类型,访问速度更快,尤其是考虑了internet应用的需要。使用ADO连接不需要通过BDE,delphi提供了一组ADO控件,它们的功能和用法与对应的BDE控件很相似。 【例】连接一个已经存在的dbase表。在设计阶段需要修改控件的若干属性,完成连接工作。 所在页 控件类 属性 值 说明 BDE TTable 代表了数据库中的一张表。是对数据库进行操作的核心控件 TTable dbaseName c:\mydbase\ttt 指定dbase表所在的目录 TTable TableName student.dbf 在该目录中选择一个表名 DataAccess TDataSource 作为数据表与可视化控件间的连接控件 TDataSource dataSet table1 把数据源连接在数据表上 Data Controls TDBGrid 用于以网格的方式显示数据 TDBgrid dataSource dataSource1 把网格控件连接到数据源 属性设置结束后,可以在设计阶段把Table1的Active属性设为True,则表格中显示数据,也可以通过一个按钮的触发事件,写:Table1.active:=true 或 Table1.open来完成。 当数据表被激活以后,我们就可以在网格中浏览数据,并且可以修改数据。有的时候,不希望用户改变数据。怎么实现只读设置呢?上图启发我们有三种方法。①table1.readOnly属性 为true ②dataSource1.autoEdit属性为false ③dbgrid1.options中的dgEditing:=false ◇凡是我们在设计阶段所做的选择,都可以用程序的方法实现,而且我们也鼓励这样做。因为我们读别人的程序的时候,从一大堆属性中要区分哪些是系统默认的,哪些是后来设定的是一件十分耗时且枯燥的工作。 ◇如果我们的工作并不需要显示数据,则只要一个TTable控件就可以对表进行操作了。 【例】通过TTable控件创建dbase数据表。 table1.databaseName := 'c:\mydabse\tt'; table1.tableName := 'test.dbf'; with table1.fieldDefs.addFieldDef do begin name:='K'; dataType := ftString; size := 10; end; with table1.fieldDefs.addFieldDef do begin name:='V'; dataType := ftInteger; end; table1.createTable; ◇我们甚至可以不同窗体上的table1控件,可以直接创建一个TTable对象,使用后,把它释放。var t: TTable ... t := TTable.creaet(self);try ... finally t.free end; TTable是从TDataSet(数据集)类继承的。有许多对数据库操作的控件类都是从TDataSet继承的。TDataset从概括的高度,定义了对记录的导航,增,删,改等操作,它是数据操纵的核心。 四、核心对象TDataSet TDataSet代表一张二维表。表是记录的集合。记录是字段的数组。 ◇只是
本文档为【Delphi培训课程】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_698131
暂无简介~
格式:doc
大小:251KB
软件:Word
页数:27
分类:互联网
上传时间:2013-04-06
浏览量:6