Delphi讲义电子科技大学讲师,屈鸿电话,13198563731
信箱,croacer@etang.com
Qq:3004887
第二讲 面向对象程序设计基础构成 delphi的语言基础,严格地说,不是
pascal而是 object pascal;后者不是对前者的简单扩充和升级,而是思想上,
结构上的全面革新。贯穿 object pascal
始终的概念是对象。
主要内容:
1.面向对象程序设计初步
2.面向对象的原理
3.面向对象的 delphi实现一,面向对象程序设计初步
*面向过程的程序设计( POP)
* 面向对象的程序设计( OOP)
1,POP (Procedure-Oriented Programming)
POP是一种基于功能分析的、以算法为中心的程序设计方法,
由若干个过程(函数)组成 。
POP是一种传统的程序设计方法,开发过程的步骤为,
● 系统分析
● 系统初步设计
● 算法详细设计
● 程序编码设计
● 程序测试
● 程序维护例:
BASIC,PASCAL,C等一个面向过程的程序设计语言应具备的机制:
数据描述:常量、变量
完备的运算符与表达式规则
流程控制与模块化功能
2。 OOP (Object-Oriented Programming)
OOP是一种基于结构分析的、以数据为中心的程序设计方法,活动的基本单位是对象,向对象发送消息可以激活对象的行为。
程序 = 对象 + 消息传递
( 1)对象和类
在我们所处的客观世界中,每一个有明确意义和边界的事物都可以看作是一个对象 ( O b j e c t ),这些对象有自己的属性,对象与对象之间还有一定的相互关系。如人和电视机。
我们可以把具有相似特征的事物归为一类,也就是把具有相同属性的对象看成一个类 ( c l a s s )。比如,
所有的电视机可以归成一个“电视机类”,所有的人可以归成一个“人类”。
一个对象是对一个客观实体的属性(数据)和行为
(方法)的封装体
( 2)消息包括:接受消息的对象(目标对象)
需要执行的操作(方法选择器)
所传递的参数
( 3)面向对象程序设计语言例,borland c++
delphi,c++builder,visual c++、
visual foxpro,powerbuilder,java等
( 4)面向对象程序设计语言应支持的机制
支持抽象数据类型
继承
多态性
类属(模板)
( 5)面向对象程序设计的优点
模型的有效性空间大
有较好的可重用性
适合于开发较大规模的程序二,面向对象的原理
△ 面向对象是与面向过程相比较而言的,面向过程的结构化设计方法被广泛使用,但在代码量增大时( 1万行以上)有许多困难难以克服。比如全局变量不容易控制;重用性不好等。
△ 对象是对具有独立性质的事物的抽象,我们考察对象时,只关心对象的性质和行为,而不关心对象的内部实现机制。对象的最大优点是可重用性。
△ 对象间可以通过消息的传递来相互影响,协作完成某个特定的任务。
△ 与对象有关的三个概念:封装,继承与多态。
1.封装的含义封装不是简单地装起来,比如记录结构,比如子目录结构。
封装的真正含义是隐藏,就是隐藏代表对象状态的内部数据。
函数象一部加工机器而对象保存自己的状态对象不能用函数加全局变量实现,因为对象的数据是私有的,外界不能直接访问;
多个同类型的对象可同时存在,且状态不同。
2.封装的内容封装的内容是私有的数据和操作。但如果私有的东西完全不能被访问则没有意义。不能被外界感知的东西对外界来说就是不存在的。所以要对外界提供访问接口:属性和方法。属性和方法是对被封装的内容的曲折的反映和间接的操纵。
3.对象和类定义对象的性质的程序文档,称为类。类并不存在于内存中。通过类可以生成或说制造出多个同属于一个类型的对象。这个过程称为实例化。
4,理解继承用于描述多种对象的文档可能有许多相似的地方。我们可以通过继承的方法减少这种重复描述的文档。继承就是指出某个文档包含其他文档中描述的特征 。
● 继承是文档的特征,因而只是对类而言的。 对象是内存中实例,对对象而言,不存在继承的概念 。当观察一个对象实例的时候,我们并不知道它是否是通过继承的方式被构造的。
● 继承并不一定必须是上下级的关系 。只要有相似的地方,就可以使用继承,继承的目的之一是为了省写代码,即代码重用。
● 在定义类的时候,继承提供了极大的方便。这启发我们定义一些描述多种对象性质的抽象的类。 这些类不能生成实例对象,它们的唯一作用就是为其他的类描述提供继承。
5,多态多态是面向对象的精髓。一般来说,多态指对同样的消息,
不同的响应。静态多态通过函数重载来实现;狭义的多态指在编译时无法确定要调用的函数的地址的现象。
例子,从劳动者类继承的农民,工人和其他劳动者,从农民类继承的青年农民中,有些定义了劳动这个动作
.劳动
.劳动
.劳动劳动者农民工人其他青年农民
● 形成多态的前提,抽象地看待一个对象 。把农民,青年农民,工人都抽象地当作劳动者来处理。这种处理方法叫做泛化
● 在调用一个被泛化的对象的方法时,一般我们并不是希望调用抽象类的方法,而是希望执行对该对象而言,最具体的方法。因为在编译时无法确定被泛化的对象的真正类型,因而就无法确定要执行的函数的地址,
从而产生多态的现象
● 多态的实施是通过在运行时保存类型信息的办法来实现的 。类型信息是关于类的全体的公共信息,不是专属于某一个特定的对象。
● 多态的方法使我们站在概括的高度来处理对象,抽象思维是人类的特点和优点,多态的使用充分发挥了这种优势。
● 继承的目的之二就是要产生多态的能力。这是继承的重要目标
6,面向对象设计原则面向过程的设计方法=数据结构+算法面向过程的设计方法=对象+消息
● 对象要有独立的特点,就是不依赖或较少地依赖于外界,必须能够明确地指出哪些属于对象,哪些不属于对象 。
● 对象要能完成相对独立的功能 。对象的定义一般从功能的定义入手
● 对象要保护自己的数据,使外界无法干涉对象的独立性。同时,对象的方法应该操作自己的数据,而不是去他人的数据。
● 对象对外界的影响是通过向其他对象发送消息来实现的。尽量避免直接操作外部的数据结构。
7.面向对象的思想的实现要兼顾到运行效率的问题。
就效率而言,c++ > delhi > Java > smallTalk。
就面向对象的彻底性而言,则刚好相反二,面向对象的 delphi实现
1,类的定义 type 类名 =class(父类 ),.,end
△ 不写父类,表示从 TObject 继承,这时,括号也不写 ;
△ 不支持多重继承。 可以通过支持接口的方法实现多重继承的类似功能可以把类的用户分成三组:
①自己:就是类的成员函数
②子孙:就是从本类直接或间接继承的类的成员函数
③他人:就是除此以外的其他函数
2.保护方式 关键字 private protected public published
● published与 public有相同的保护效果。但 publised修饰的成员可以在设计时出现在对象浏览器中。注意,这不是 delphi的内部功能,因为对象浏览器也是用 delphi写的。
● 有一个特例:处于同一单元的定义,可以自由访问,忽略保护方式描述字
● 保护方式也是一个前缀,不是域的概念,后边无冒号,注意与 C
的区别。
private protected public Published
自己 允许 允许 允许 允许子孙 禁止 允许 允许 允许他人 禁止 禁止 允许 允许
3,类操作符 ――is和 as
① is的用法:表达式“对象 is类”返回一个布尔类型。如,猫是猫类;
猫是动物类。
② as的用法:表达式“对象 as类”返回该对象,但类型已经强制为后边的类所指定的类型。这种表达方法叫特化。
③二者经常联合使用。 if a is TA then (a as TA).caption,=,.,
在内存中,只存储对象的私有数据,而方法只有一个拷贝,与其他函数一起存于静态空间。对象在定义的时候,只是一个指针(4字节)并无对象的实体。必须调用类的构造方法才能生成对象。该对象存于堆空间中。对象在使用完毕后,需要调用它的析构函数来完成对内存的释放。
在 delphi中,一般不直接调用析构函数,而是调用 free函数,这是更安全的方法。
4.对象存储结构
5.构造函数构造函数是特殊的函数,严格地说它不是成员函数,构造函数完成内存申请和初始化成员变量的作用。
构造顺序是先构造祖先,再构造自己。
◇ 定义,constructor create;或 constructor create(参数列表 );
◇构造函数的实现中一般多要先调用祖先的构造函数。方法是:
inherited create..
◇ 定义两个构造函数时,要用 overload关键字表示重载,这是静态多态的例子。
6.析构函数析构函数是成员函数 。 析构函数是动态多态的典型例子 。 当一个对象被抽象地处理时,一定要调用属于这个对象的类所定义的析构函数 。 而不是抽象类的析构函数 。
析构的顺序是,先析构自己,再析构祖先,和构造正相反 。
◇ 定义,destructor destroy; override;
◇在实现的时候,不写 override。这个关键字指示着该名字的函数在运行中要做动态多态处理。
◇一般来说,析构函数的末尾总是调用祖先的析构函数。 inherited;
多态特征的函数不需要指明要调用的祖先函数名。
◇与 C++不同,delphi的构造函数和析构函数都不会被编译器自动调用,
必须显式地调用。
7.替换与覆盖替换是根据局部优先的原则,用同名的成员代替祖先定义的成员 。 这是为了屏蔽祖先定义的某个方法或数据 。
覆盖则是把祖先定义的方法具体化,或说特化 。 这是实现多态的基础 。
实现覆盖的方法:①父类声明中加 virtual;②子类声明中加
override;③子类实现中不加。
◇用 dynamic 和 virtual 具有同样的逻辑含义,只是实现的方式不同。
◇有时,覆盖的方法也称虚方法或动态方法。
只定义不实现的虚方法称抽象方法。至少含有一个抽象方法的类称为抽象类。抽象类型不能实例化,只能供给其他类做继承之用。
8.抽象类