XiaoHui.net 笑汇程序员论坛首页
工作并快乐着,职业并休闲着
寻梦的岁月从不言辛苦几许,
不问收获几多……
» 游客:  申请新用户 | 登录 | 会员 | 统计 | 帮助 » XiaoHui.Net 笑汇程序员论坛 | 纯文字版 | 全站索引 | XiaoHui.com


[原创心得] 面象对象编程 随笔0

RSS 订阅当前论坛  

上一主题 下一主题
     

标题: [原创心得] 面象对象编程 随笔0  
 
安羽
小水手
Rank: 1



UID 2194
精华 0
积分 13
帖子 13
阅读权限 10
注册 2006-2-28
状态 离线
面象对象编程 随笔0

面象对象编程 提出许多年了 但许多程序(员)爱好者至今还在可视化面向对象开发环境中却还继续写着过程式的代码

这是PB的Source代码
虽与VB语法不同但使用面象对编程的思想是相同的

VB的面象对象编程方法与实践 我有时间再写.

forward
global type cdefaultreveivers from nonvisualobject
end type
end forward

global type cdefaultreveivers from nonvisualobject
end type
global cdefaultreveivers cdefaultreveivers

type variables
private:
CUser mUser[]
datastore mDsDefaultReveivers
long mCount=0

end variables

forward prototypes
public function cuser item (integer _index)
public function integer initialize (integer _contracttypecode, integer _flownodecode)
public function long count ()
end prototypes

public function cuser item (integer _index);try
if _index>0 and _index<=mCount then
        string userid
        userid=mDsDefaultReveivers.object.ReceiverUserID[_index]
        if not isvalid(mUser[_index]) then
                mUser[_index]=create CUser
        end if
        if mUser[_index].initialize(userid )<=0 then
                destroy(mUser[_index])
        end if
        return mUser[_index]
else
        CUser tmp
        return tmp
end if
catch(runtimeerror er)
        MessageBox("提示",er.getmessage())
end try


end function

public function integer initialize (integer _contracttypecode, integer _flownodecode);
if not isvalid(mDsDefaultReveivers) then
        mDsDefaultReveivers=create datastore
        mDsDefaultReveivers.dataobject="d_defaultreveivers_by_ContractTypeCode_FlowNodeCode"
        mDsdefaultreveivers.settransobject( sqlca)
end if

mCount=mDsdefaultreveivers.retrieve( _contracttypecode, flownodecode)
//Messagebox(string(mcount),string(_contracttypecode)+"%"+string(_flownodecode))
if mCount>0 then
        CUser Usertmp
        mUser[mCount]=Usertmp
        return 1
else
        return -1
end if
end function

public function long count ();return mCount
end function

on cdefaultreveivers.create
call super::create
TriggerEvent( this, "constructor" )
end on

on cdefaultreveivers.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on
2006-4-20 16:30#1
查看资料  Blog  发短消息  顶部
 
YunHai
版主
Rank: 7Rank: 7Rank: 7



Medal No.1  
UID 5004
精华 0
积分 5934
帖子 5934
阅读权限 100
注册 2002-1-12
来自 黑龙江
状态 离线
vb是基于对象的开发工具
2006-4-25 23:09#2
查看资料  Blog  发短消息  顶部
 
muzhu
小水手
Rank: 1



UID 21362
精华 0
积分 24
帖子 24
阅读权限 10
注册 2006-4-22
状态 离线
我也来贴一点,望楼主不要见怪。

Visual Basic 是如何提供多态的

大多数面向对象的程序设计系统,都是通过继承来提供多态的。也就是说,设想的 Flea 和 Tyrannosaur 类可能都是从某个 Animal 类继承来的。每个类都将重写 Animal 类的 Bite 方法,以提供自己的噬咬特点。

多态来自于这个事实:可以调用属于某类对象的 Bite 方法—该类可以是从 Animal 中派生出来的任意类,而不必知道该对象到底属于哪一个类。

提供多态接口
Visual Basic 不用继承来提供多态。Visual Basic 是通过多重 ActiveX 接口来提供多态的。在构成 ActiveX 规格说明基础的部件设计模型 (COM) 中,多重接口允许软件部件系统在不扩散现有代码的情况下进行展开。

一个接口是一组相关的属性和方法。ActiveX 规格说明的许多内容是关于实现一些标准接口的,这些标准接口是用来获得系统服务或者为其它程序提供功能。

在 Visual Basic 中,可以创建一个 Animal 接口,并用自己的 Flea 和 Tyrannosaur 类予以实现。然后就可以调用任何一种对象的 Bite 方法,而无须知道它到底是哪一种对象。

多态和性能
从性能方面考虑,多态是很重要的。为了认识这一点,考虑下面的函数:

Public Sub GetFood(ByVal Critter As Object, _
ByVal Food As Object)
   Dim dblDistance As Double
   ' 计算到食物所在处距离的代码(略)。
   Critter.Move dblDistance   ' 后期绑定
   Critter.Bite Food            ' 后期绑定
End Sub

对 Critter 来说,Move 方法和 Bite 方法是后期绑定的。后期绑定在 Visual Basic 编译时不能决定变量包含何种对象时发生。在本示例中,Critter 参数被声明为 As Object,因此在运行时,它可能包含对任何类型对象引用,如 Car 或者 Rock。

因为它不可能指明对象将是什么,所以 Visual Basic 编译一些附加的代码,用这些代码来询问该对象是否支持已经调用的方法。如果该对象支持这种方法的话,那么附加的代码将调用它;反之,附加的代码将会产生一个错误。每种方法或者属性的调用都会引入这个额外开销。

相比较而言,接口则允许前期绑定。当 Visual Basic 在编译时明确知道正在调用什么样的接口时,它将检查一下类型库,看看那个接口是否支持该方法。然后 Visual Basic 就可以用一张虚拟函数表 (vtable),按直接跳转到该方法进行编译。这样做比起后期绑定来要快许多倍。

现在,假设 Move 和 Bite 方法属于 Animal 接口,而且动物的所有类都提供该接口。Critter 参数现在就可以被声明为 Animal 了,而且 Move 和 Bite 方法也将是前期绑定的:

Public Sub GetFood(ByVal Critter As Animal, _
ByVal Food As Object)
   Dim dblDistance As Double
   '计算到食物所在处距离的代码(略)。
   Critter.Move dblDistance   '前期绑定 (vtable)。
   Critter.Bite Food            '前期绑定 (vtable)。
End Sub

详细信息   在下面“创建和实现接口”这一节中,创建了一个 Animal 接口,并在 Flea 和 Tyrannosaur 类中实现它。
2006-4-26 08:37#3
查看资料  Blog  发短消息  顶部
 
muzhu
小水手
Rank: 1



UID 21362
精华 0
积分 24
帖子 24
阅读权限 10
注册 2006-4-22
状态 离线
创建和实现接口

如上面“Visual Basic 是如何提供多态的”中所解释的,所谓接口,就是一组属性和方法。在下面的代码示例中,将创建一个 Animal 接口,并在两个类— Flea 和 Tyrannosaur 中实现它。

创建该 Animal 接口的方法是:将一个类模块添加到工程中,将它命名为 Animal,并插入到下面的代码中:

Public Sub Move(ByVal Distance As Double)

End Sub

Public Sub Bite(ByVal What As Object)

End Sub

注意,在这些方法中并没有任何代码。Animal 是一个抽象类,不包含实现的任何代码。抽象类不是用来创建对象的—其用途是为添加其它类中的接口提供模板。(尽管,已经证明,有些时候实现一个非抽象类的接口是有用的;这将在本节主题的后面进行讨论。)

注意   确切地说,一个抽象的类是不能从中创建对象的类。从 Visual Basic 的类中总是可以创建对象的,即使它们不含有代码,它们也不是真正抽象的。

现在,就可以添加另外两个类模块了,这两个类模块一个叫 Flea,另一个叫 Tyrannosaur。为了在 Flea 类中实现 Animal 接口,要用到 Implements 语句:

Option Explicit
Implements Animal

一旦将这行代码添加进去,就可以单击代码窗口中左边(“对象”)下拉菜单。其中一个登录项将是 Animal。当选择了它时,右边(“过程”)下拉菜单上将显示 Animal 接口的方法。

依次选择每种方法,可为所有的方法创建空白过程模板。这些模板将具有正确的参数和数据类型,就象在 Animal 类中所定义的那样。每个过程名都将以 Animal_ 前缀来标识该接口。

重点   一个接口就象一个契约。实现接口后,当调用该接口的任何属性或者方法时,一个类已经约定好要作出反应。因此,必须实现接口的所有属性和方法。

现在,就可以将下面的代码添加到 Flea 类中了:

Private Sub Animal_Move(ByVal Distance As Double)
   '(跳过多少英寸的代码,略。)
   Debug.Print "Flea moved"
End Sub

Private Sub Animal_Bite(ByVal What As Object)
   '(吃了多少生命的代码,略。)
   Debug.Print "Flea bit a " & TypeName(What)
End Sub

可能想知道为什么这些过程被声明为 Private。如果它们是 Public,那么 Animal_Jump 和 Animal_Bite 过程将成为 Flea 界面的一部分,这样将被困在跟原先所在的同样的圈子中,将 Critter 参数声明为 As Object,这样它就可能包含一个 Flea 或者一个 Tyrannosaur。

多重接口
现在,Flea 类有了两个接口:刚刚实现的 Animal 接口—它有两个成员,以及缺省的 Flea 接口—它没有任何成员。该示例的后面,将把一个成员添加到缺省接口的其中一个。

类似地,可以为 Tyrannosaur 类实现 Animal 接口:

Option Explicit
Implements Animal

Private Sub Animal_Move(ByVal Distance As Double)
   '(跳起多少码的代码,略。)
   Debug.Print "Tyrannosaur moved"
End Sub

Private Sub Animal_Bite(ByVal What As Object)
   ' (拿起一磅肉的代码,略。)
   Debug.Print "Tyrannosaur bit a " & TypeName(What)
End Sub

练习 Tyrannosaur 和 Flea
将下列代码添加到“Form1”的 Load 事件中:

Private Sub Form_Load()
   Dim fl As Flea
   Dim ty As Tyrannosaur
   Dim anim As Animal

   Set fl = New Flea
   Set ty = New Tyrannosaur
   '首先看一下 Flea。
   Set anim = fl
   Call anim.Bite(ty)   'Flea 叮咬 dinosaur。
   '现在轮到 Tyrannosaur。
   Set anim = ty
   Call anim.Bite(fl)   'Dinosaur 咬 flea。
End Sub

按 F8 键,单步执行代码。注意“立即”窗口中的信息。当 变量 anim 包含对 Flea 的引用时,就调用该 Flea 的 Bite 实现,同样的,对于 Tyrannosaur 来说,情况也是如此。

变量 anim 可以包含对实现 Animal 接口的任何对象的引用。事实上,它只能包含对这种类型对象的引用。如果试图将一个 Form 或者一个 PictureBox 对象赋给 anim 的话,那么将会产生错误。

当通过 anim 来调用 Bite 方法时,该方法是前期绑定的,因为 Visual Basic 在编译时知道,不论将什么对象赋给 anim,该对象都将有一个 Bite 方法。

将 Tyrannosaurs 和 Fleas 传递给过程
回忆一下“Visual Basic 如何提供多态?”("How Visual Basic Provides polymorphism?")中的 GetFood 过程。可以将 GetFood 过程的第 2 个版本—演示多态的版本—添加到“Form1”中,并用下面的代码来取代 Load 事件中的代码:

Private Sub Form_Load()
   Dim fl As Flea
   Dim ty As Tyrannosaur

   Set fl = New Flea
   Set ty = New Tyrannosaur
   'Flea 在恐龙上吃饭。
   Call GetFood(fl, ty)
   '相反的情况。
   Call GetFood(ty, fl)
End Sub

单步执行上述代码,显示作为传递给另一接口类型参数的对象引用,是怎样转换为对第二个接口(在这里是 Animal)的引用的。所发生的情况是: Visual Basic 查询该对象,看看该对象是否支持第二个接口。如果该对象支持的话,它将返回对该接口的引用,于是 Visual Basic 将返回的引用放置到参数变量中。如果该对象不支持第二个接口,将会出现错误。

实现返回值的方法
假设 Move 方法返回一个值。不管怎么说,自己知道想让 Animal 移动多远的距离,但是,各个实例不可能都移动那么远。它可能又老又弱,或者在路上可能恰好有一堵墙。可以用 Move 方法的返回值来说明该 Animal 实际移动了多远的距离。

Public Function Move(ByVal Distance As Double) _
As Double

End Function

在 Tyrannosaur 类中实现该方法时,把返回值赋给过程名,这跟处理任何其它 Function 过程一样:

Private Function Animal_Move(ByVal Distance _
As Double) As Double
   Dim dblDistanceMoved As Double
   '计算能弹跳多远(基于对年龄、健康状态和障碍物的
   '考虑)的代码,略。
   '该示例假设已经将结果放置到变量 dblDistanceMoved 中。
   Debug.Print "Tyrannosaur moved"; dblDistanceMoved
   Animal_Move = dblDistanceMoved
End Function

为了返回值的赋值,使用全过程名,包括接口前缀。

详细信息   所实现的接口,除方法外还可以有属性。下面“实现属性”讨论了属性实现的方式上的一些不同之处。
2006-4-26 08:38#4
查看资料  Blog  发短消息  顶部
 
muzhu
小水手
Rank: 1



UID 21362
精华 0
积分 24
帖子 24
阅读权限 10
注册 2006-4-22
状态 离线
实现属性

本主题继续讨论“创建和实现接口”开始的代码示例,将属性添加到用 Flea 和 Tyrannosaur 类所实现的 Animal 接口中。当然,在开始该主题前,阅读一下那个主题是有帮助的。

假设要将 Age 属性赋予 Animal 类—通过将一个 Public 变量添加到声明部分:

Option Explicit
Public Age As Double

现在,在 Tyrannosaur 和 Flea 类的代码模块的“过程”下拉菜单上,将包含实现 Age 属性的属性过程,如下图 9.10 所示。

图 9.10   属性过程的实现



这里图示了本章前面的“向类中添加属性”中的一个要点。严格说来,用公有变量实现属性对于编程者来说是很方便的。此含义的背后,Visual Basic 是用一对属性过程来实现该属性。

必须实现两个过程。通过在私有数据成员中保存值,实现属性很容易,如下所述:

Private mdblAge As Double

Private Property Get Animal_Age() As Double
   Animal_Age = mdblAge
End Property

Private Property Let Animal_Age(ByVal RHS As Double)
   mdblAge = RHS
End Property

私有数据成员是一个实现细节,必须自己添加。

注意   当 Implements 为 Property Set 或者 Property Let 提供模板时,并没有任何办法来确定最后一个参数的名字,因此代之以名字 RHS,如上述代码示例所述。

在作为公有数据成员实现的属性上,没有对数据的有效性进行验证,但是那并不意味着不能将 Animal_Age 有效性验证的代码添加到 Property Let 中。例如,可能想分别为 Tyrannosaur 或者 Flea 限制其值为合适的年龄。

事实上,这意味着接口和实现的X$%@X性。只要接口跟类型库中的描述相匹配,实现可以是任意的。

在进行下一步之前,从两个类模块中删除读写 Age 属性的实现部分。

实现只读属性
当然,允许任意设定一个动物的年龄,是一种糟糕的对象设计。对象应该知道自己的年龄,并将这个年龄作为一种只读属性提供给用户。从 Animal 类中删除公有变量 Age,并为只读年龄属性添加模板,如:

Public Property Get Age() As Double

End Property

现在,Tyrannosaur 和 Flea 类代码窗口的“过程”下拉菜单上,仅包含一个登录项,即 Age [PropertyGet]。对 Tyrannosaur 可这样实现:

Private mdblBirth As Double

Private Property Get Animal_Age() As Double
   Animal_Age = Now - mdblBirth
End Property

上述代码返回 Tyrannosaur 按日计算的年龄。可以在 Tyrannosaur 类的 Initialize 事件中设置 mdblBirth,如:

Private Sub Class_Initialize()
   mdblBirth = Now
End Sub

当然,也可以用更常用的单位来返回属性值,比如犬类的寿命。

详细信息   已经正在到处引申接口和对象的概念,把它们看作是同样的东西,而表面看来则是把对对象的引用放置到对象变量中,把对接口的引用放置到另一个对象变量中。“关于对象和接口的简要补充讨论”澄清许多问题。
2006-4-26 08:38#5
查看资料  Blog  发短消息  顶部
 
muzhu
小水手
Rank: 1



UID 21362
精华 0
积分 24
帖子 24
阅读权限 10
注册 2006-4-22
状态 离线
关于对象和接口的简要补充讨论

本主题,将完成从“创建和实现接口”开始,并在“实现属性”中继续讨论的那个代码示例。当然,在开始这个主题之前,阅读一下那些主题是有帮助的。

这个 Tyrannosaur 和 Flea 代码示例,看起来似乎用接口和对象来解决很快,也很轻松。把对象的引用赋给一个对象变量,把接口的引用赋给另一个对象变量。

事实上,所有的引用都是对象的引用。对一个接口的引用也是对实现接口的对象的引用。而且,一个对象可能有多个接口,但在底层它仍然是同一对象。

在 Visual Basic 中,每个类都有一个缺省的接口,该接口具有与类相同的名字。是的,几乎都是同样的。按照惯例,在类名前加一条下划线。该下划线指明了这个接口是隐藏在类型库里的。

这样,Tyrannosaur 类就有一个缺省名为 _Tyrannosaur 的接口。因为 Tyrannosaur 同时实现 Animal,所以该类还有第二个接口(其名为 Animal)。

不过,在它的所有底层,对象仍然是 Tyrannosaur。将一个命令按钮放置到“Form1”上,并添加下面的代码:

Private Sub Command1_Click()
   Dim ty As Tyrannosaur
   Dim anim As Animal

   Set ty = New Tyrannosaur
   Set anim = ty
   MsgBox TypeName(anim)
End Sub

可能期望信息框显示 "Animal",但是,事实上显示的是 "Tyrannosaur"。

查询接口
当把 Tyrannosaur 对象赋给 Animal 类型的变量时,Visual Basic 将询问该 Tyrannosaur 对象它是否支持 Animal 接口。(为此所用的方法为 QueryInterface,或者简称 QI;有时可能遇到 QI 作为动词使用。)如果回答是否定的,将会产生错误。

如果回答是肯定的,该对象将被赋给变量。只有通过这个变量 Animal 接口的方法和属性才可被访问。

类属对象变量和接口
如果将对象引用赋给类属对象变量,(如下列代码所示),将会出现什么情况?

Private Sub Command1_Click()
   Dim ty As Tyrannosaur
   Dim anim As Animal
   Dim obj As Object

   Set ty = New Tyrannosaur
   Set anim = ty
   Set obj = anim
   MsgBox TypeName(obj)
End Sub

结果得到另一个 Tyrannosaur。现在,通过变量 obj 调用属性和方法时,得到什么接口?将下面的方法添加到 Tyrannosaur 类中:

Public Sub Growl()
   Debug.Print "Rrrrrr"
End Sub

Growl 方法属于 Tyrannosaur 对象的缺省接口。在命令按钮的 Click 事件的代码中,用下面的两行代码来取代 MsgBox 语句:

obj.Move 42
obj.Growl

当运行这个工程并单击按钮时,执行将在 Growl 方法上停止,并返回错误信息“对象不支持此属性或方法”。很明显,接口仍然是 Animal。

Object 类型的变量和具有多重接口的对象一起使用时,必须记住某些事情。该变量将访问的接口是最后赋值的接口。例如:

Private Sub Command1_Click()
   Dim ty As Tyrannosaur
   Dim anim As Animal
   Dim obj As Object

   Set ty = New Tyrannosaur
   Set anim = ty
   Set obj = anim
   obj.Move 42      '成功
   obj.Growl      '失败

   Set obj = ty
   obj.Move 42      '失败
   obj.Growl      '成功
End Sub

幸好,很少将这种比较慢的、后期绑定的 Object 数据类型和具有多重接口的对象一起使用。使用多重接口的一个主要原因是,通过多态可以得到前期绑定的好处。

其它接口源
Visual Basic 的类模块不是唯一的实现接口的源。可以实现类型库包含的各种接口,只要该接口支持 Automation。

如果有 Visual Basic 专业版或企业版,那么可以创建自己的抽象类的类型库。这些类型库可能在许多工程中用到,就象在《部件工具指南》中,“创建 ActiveX 部件”中的“部件设计的一般准则”中所描述的那样。

专业版和企业版在 Tools 目录都包括有 MkTypLib (Make Type Library) 实用工具。如果已经用 Microsoft Visual C++ 使用过该实用工具,就会发现这是创建接口的一条更适宜的途径。

在工程中使用接口
为了在工程中使用接口,可以在“工程”菜单上单击“引用”,打开“引用”对话框。如果类型库已经注册,那么它将出现在引用列表中,于是可以复选它。如果类型库不在该列表中,可以使用“浏览”按钮对它定位。

一旦有了对某个类型库的引用,就可以使用 Implements 来实现该类型库包含的任何 Automation 接口。

详细信息   并没有限制一定要实现为抽象接口。下面的“代码重用的许多(内部)方面”中描述了怎样实现一个接口,以及选择性地重用该接口提供的类的属性和方法。
2006-4-26 08:39#6
查看资料  Blog  发短消息  顶部
 
muzhu
小水手
Rank: 1



UID 21362
精华 0
积分 24
帖子 24
阅读权限 10
注册 2006-4-22
状态 离线
代码重用的许多(内部)方面

有两种主要的代码重用窗体—二进制和源代码。二进制代码重用,是通过创建和使用一个对象来实现的,而源代码重用,则是通过继承来实现的— Visual Basic 不支持。(源代码重用也可以通过复制和修改源代码来实现,但这种技术没有什么新意,而且存在许多人所共知的问题。)

Visual Basic 已成为二进制代码重用的先驱—控件就是典型的例子。通过将控件的实例放置到窗体上就可以重用该控件中的代码。这被称为包含(containment) 关系或者具有 (has-a) 关系;也就是说,该窗体包含或者具有CommandButton。

详细信息   包含关系在本章后面的“对象模型”作了讨论。

委派给实现的对象
Implements 提供了代码重用的一种强有力的新途径。可以实现一个抽象类(就象在“创建和实现接口”中所讨论的那样),或者也可以实现一个全功能类的接口。可以在外部对象(即,实现内部对象接口的那个对象)的 Initialize 事件中创建内部对象(即,所实现的对象)。

就象在“创建和实现接口”中所提到的那样,接口就象契约一样—必须在外部对象的类模块中实现内部对象接口的所有成员。不过,在委派内部对象的属性和方法为代表方面,可以有很多选择。在一个方法中,可能直接委派一个内部对象为代表,传递未更改的参数,而在另一种方法中,可能执行在调用该内部对象之前自己的部分代码,在第三种方法中仅仅执行自己的代码,而完全忽略内部对象!

例如,假设有一个 OneManBand 类和一个 Cacophony 类,这二者都产生声音。希望把 Cacophony 类的功能添加到 OneManBand 类中,并重用 Cacophony 类方法的一些实现。

'OneManBand 实现 Cacophony 接口。
Implements Cacophony

'保存引用的对象变量。
Private mcac As Cacophony

Private Sub Class_Initialize()
   '创建对象。
   Set mcac = New Cacophony
End Sub

现在,就可以在“对象”下拉菜单上选择 Cacophony,然后为 Cacophony 接口的方法获得过程模板。为了实现这些方法,可以委派给 Cacophony 对象。例如,Beep 方法可能看起来如下所示:

Private Sub Cacophony_Beep(ByVal Frequency As Double, _
ByVal Duration As Double)
   '委派给内部的 Cacophony 对象。
   Call mcac.Beep(Frequency, Duration)
End Sub

上面的实现是非常简单的。外部对象 (OneManBand) 直接委派给内部对象 (Cacophony),不作任何更改即可重用 Cacophony 对象的 Beep 方法。这是一件好事,但仅仅只是个开端。

Implements 语句对于代码重用来说,是一个非常强大的工具,因为它给予很大的灵活性。可能想更改 OneManBand 类的 Beep 方法的效果,方法是在对内部 Cacophony 对象的调用之前(或之后),插入自己的代码:

Private Sub Cacophony_Beep(ByVal Frequency As Double, _
ByVal Duration As Double)
   '撞击每一件东西升高八度。
   Frequency = Frequency * 2
   '基于 OneManBand 类的另一个属性,即 Staccato,
   '分割每个嘟嘟声的持续时间。
   If Staccato Then Duration = Duration * 7 / 8
   Call mcac.Beep(Frequency, Duration)
   '甚至可以调用 OneManBand 的其它方法。
   If Staccato Then Pause(Duration * 1 / 8)
End Sub

对于这些方法来说,实现可能会直接委派内部 Cacophony 对象为代表,而对于另外一些来说,可能在委派之前或之后插入自己的代码—或者甚至完全忽略委派,而完全用自己的代码来实现一种方法。

因为 OneManBand 类实现 Cacophony 接口,所以可以将它和调用该接口的任何音乐应用程序一起来使用。其实现细节可从调用应用程序处隐藏起来,但是结果发出的声音都是自己的。

注意   COM 提供了另一个机制进行二进制代码重用,该机制叫凝聚。在集合中,无更改地重用一个完整的接口,而且该实现是由被凝聚的类的一个实例所提供的。Visual Basic 不支持这种代码重用的窗体。

这样一来不冗长乏味吗?
写委派代码的确可能变得冗长乏味,如果大部分外部对象的属性和方法,只是简单地直接委派给相对应的内部对象的属性和方法的时候,尤其是这样。

如果有 Visual Basic 专业版或企业版,就可以使用“Visual Basic 扩展性”模型,创建自己的委派向导,使任务自动化,类似于专业版和企业版中的“类向导”一样。
2006-4-26 08:39#7
查看资料  Blog  发短消息  顶部
 
xjb
传说中的水手
Rank: 5Rank: 5



UID 18
精华 0
积分 2820
帖子 2820
阅读权限 1
注册 2002-2-4
状态 离线
vb实现面向对象太累,也不纯正!
2006-4-30 11:47#8
查看资料  Blog  发短消息  顶部
 
project11
版主
Rank: 7Rank: 7Rank: 7


UID 2246
精华 0
积分 330
帖子 330
阅读权限 100
注册 2006-3-3
来自 北京
状态 离线
我认为面向对象只是一种思想,而程序的具体实现还是离不开过程的,仅属个人意见。

实践
2006-5-7 14:28#9
查看资料  访问主页  Blog  发短消息  顶部
 
xjb
传说中的水手
Rank: 5Rank: 5



UID 18
精华 0
积分 2820
帖子 2820
阅读权限 1
注册 2002-2-4
状态 离线
思想总归要付诸实现的,而实现的复杂与简单就看你的选择了,如果试过用c++或者java实现面向对象,就会感觉vb实现起来够累的!
2006-5-8 09:50#10
查看资料  Blog  发短消息  顶部
     


  可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题  


 


所有时间为 GMT+8, 现在时间是 2008-12-2 20:16 Powered by Discuz! 4.1.0 清除 Cookies - XiaoHui.Net 笑汇程序员论坛 - Archiver