PB面向对象编程研究(一)

PB面向对象编程研究

1. 前言

众所周知,PowerBuilder是第四代面向对象开发语言。

面向对象程序设计的根本目的是实现数据的封装和隐藏。面向对象主要有三大特点,即封装性、继承性和多态性。

面向对象的封装性将数据与函数组织在同一个结构单元中,从而,实现数据和函数的关联以及数据对结构单元外的隐藏。进而实现结构单元与结构单元之间的弱耦合性。这里所说的结构单元就是类。

面向对象的继承性可以理解为类之间的遗传和变异。子类具有父类的性质同时又有区别于父类的性质,无论是属性还是方法。

面向对象的多态性实现的根本基础是类继承性背后的ISA关系。一个基类以及其所有派生类之间都存在ISA关系,他们的类型都属于基类类型。在实际使用中,根据对象实际的类型程序可以实现动态的方法调用。

本文主要叙述PowerBuilder面向对象的实现和特性。

 

2. 封装性

2.1. 对象

类,在PowerBuilder集成开发环境中,被称为对象Object)。在编程过程中,我们所定义的对象变量被称为该对象的一个实例(Instance。本文按照PB的习惯将类称为对象,将类的变量称为实例。

所谓的对象,我们可以认为是世间万物中任何一样东西,这件东西具有这样或者那样的特性,同时,这件东西还具有各种不同的行为。所谓的特性和行为就是我们在开发时我们所定义的数据和处理数据的函数。在面向对象的设计中,数据成员又称为属性,函数又称为方法。

2.2. 属性

属性即对象的特性,是编程过程中我们要处理的数据。在PB中,属性的表现形式为对象的实例变量instance variable。属性一般有三种访问权限(access right),即:

Public公共

Protected保护

Private私有

公共访问权限指不仅对象内部方法可以直接访问该属性,对象外部的代码也可以直接该属性,就像我们在C/C++中使用结构体数据成员一样;保护的访问权限指对于外部代码该属性是受保护的,不允许访问,对于对象本身以及对象的后续继承对象都是公开的,可以直接访问该属性;私有访问属性是指不仅不允许外部代码访问该属性,该对象的后续继承对象也不能访问该属性,该属性为本对象的私有数据,只有对象本身可以访问。从这三种访问权限来看,似乎我们不应该定义属性的Public访问权限,因为,它违反了数据的封装和隐藏特性,我们应该定义Protected或者Private访问权限的属性,为了满足外部对特性的访问,我们只需要为该属性实现特定的访问方法。

下面几小节通过具体例子来体会一下属性访问以及初始化。

2.2.1. 访问权限

首先,我们演示在对象外部访问各种不同权限的属性。具体演示步骤如下图。我们创建一个uo_test自定义类的对象。

 

uo_test的变量声明窗口中声明如下图变量。

 

接下来,我们在Applicationopen事件中创建一个uo_test对象uo_test_1的实例,然后分别访问三个实例变量。如下图。

 

保存时PB提示我们发现错误:没有足够权限访问类uo_test的属性。

 

其次,我们演示在对象的派生对象中访问不同权限的属性。由于目前还没有涉及到如何实现继承,所以以下演示省略了派生的过程。

在下图中,我们可以从标题看出uo_test_inherited是从uo_test继承过来的。

 

在这个演示部分,我们发现,PBPrivate访问权限上与C++有所不同,虽然,PB禁止在派生类中访问Private权限的属性,但是PB的错误提示是:没有定义的变量。那么,是不是我们可以在派生类中定一个和基类中一样的属性ii_private呢?答案是否定的,PB认为在派生类中定义的这个试图覆盖基类的Private属性的变量在名字上是冲突的。如下图所示。

 

看上去很令人奇怪,提示没有定义,定义了又提示冲突,有些矛盾!而C++中的提示很明确,

如下图所示:

 

2.2.2. 可视初始化

创建一个窗口,将uo_test拖放到窗口中,查看non-visual object list窗口中uo_test_1的属性,可以看到ii_publicii_protected两个属性。这足以证明PB将实例变量作为面向对象的属性来使用的。因此,我们在PB中可以实现在可视化属性窗口中实现对象的属性初始化。如下图。

 

可能有些朋友会有疑问,为什么没有ii_private?大家可以从属性窗口的标题看出来,uo_test_1是从uo_test继承而来,所以,uo_test_1是不能访问ii_private属性的。所以,可视初始化仅针对PublicProtected访问权限的属性而言。

2.2.3. 私有属性初始化

那么私有属性该怎么初始化,那就是在基类中。

 

2.3. 方法

方法即对象的行为,是用来处理对象属性的函数。方法与属性一样,具有三种访问权限:PublicProtectedPrivate。方法可以有参数也可以没有参数,可以有返回值也可以没有返回值。

2.3.1. 参数

uo_test对象中添加一个方法func,增加一个参数,如下图:

 

图中1是传递方式,2是参数类型,3是参数名。

传递方式有有三种,如下图。

 

value表示传值方式,reference表示引用方式,readonly表示只读方式。一个好的方法设计,应该根据方法的实际情况选择参数的传递方式。选择value方式:当参数仅为传入的时候,但是在方法运行过程中需要改变该参数,例如传入一个参数表示方法中某个循环次数,修改参数做递减;选择reference方式:当参数为传出的时候,例如,方法利用该类型的参数作为方法的部分返回信息;选择readonly方式:参数仅为传入,并且在方法体内不做任何变化。选择合适的传值方式有助于正确编写和使用对象的方法(适用于普遍函数),即,从传值方式我们就能够知道该参数大致的操作性质,从而正确编写和使用。对于用户自定义类型比如结构体和类等的聚集类型,为了提高程序的性能,不建议使用value的传值方式。

参数类型有很多,点击右边的下拉键头就可以看到。同时,这个类型也可以使用用户自定义的数据类型,包括结构体、类等等,只需要将类型名字填入“Argument Type”即可。

参数名是方法体内使用的变量名,该变量通常称为形式参数。有时候,我们需要传递一个数组到方法中,那么我们可以在定义变量时在变量名后加上“[]”表示定义的参数为数组类型。在调用的过程中,将数组的名字传入即可。有时我们会看到有些人在调用这样的方法时将“[]”一并传入,从我的经验来说,这种调用方法有时会导致程序非法,所以,我个人不主张在调用方法是传入“[]”。

2.3.2. 返回值

选择合适的返回值类型。点击“Return Type”的下拉键头,我们可以选择需要的返回值类型,当然,我们也可以选择none(没有返回值)!当我们需要返回自定义数据类型时,可以将类型名称填入“Return Type”,方法就可以返回我们自定义的类型了!

 

2.3.3. 方法的调用

方法的调用也是有权限的,这一点和属性的权限类似。也分为:PublicProtectedPrivate三种。Public权限:类外部可以调用,类的子类也可以调用;Protected权限:类的外部不可以调用,类的子类可以调用;Private权限:类的外部部可以调用,类的子类也不可以调用,仅类的本身可以调用。

 

一个好的设计,应该选择合适的方法访问权限,有助于方法的正确使用,对于没有必要提供给外界的接口,要隐藏到类中。

创建func函数形如:

 

2.4. 事件

事件,PB将事件作为一个特性引入了面向对象编程的概念,指出一个对象在某种情况下应该做出什么样的反应和处理。例如,一个人在挨了另一个人一巴掌后应该怎么做?当然,人挨巴掌的时候是不能确定的,这一点正是事件的最根本特性,发生的不确定性。究竟在挨巴掌后是给予反击还是退缩就要看这个事件处理程序如何编写了。

PB中最典型的两个事件就是构造器和析构器。构造器在这一点与C++编程语言有着本质的不同。虽然C++中的构造函数都是被系统在一定时机调用(类似事件),但是,C++中可以编写各种各样特定的构造函数,而PB中为规定好的接口样式的构造器事件。

2.4.1. 构造器

构造器事件在对象创建的瞬间被调用,其功能是初始化对象属性,以及对象被创建后需要执行的方法。

 

2.4.2. 析构器

析构器事件在对象被销毁的瞬间被调用,其功能是释放对象使用的资源等的收尾工作。

 

 

阅读更多

没有更多推荐了,返回首页