.NET软件组件技术(2)

组件的继承

前面实现的将 C# 组件组合进 VB 工程中只是牛刀小试,现在我们来实现混合语言的面向对象编程( OOP ),首先,我们来尝试一下混合语言组件的继承。

新建一个 VB 类库工程 VBComponent ,在工程中按上面的方法添加对 CSharpClass.dll 组件的引用,然后组件中增加一个新类: ExtendsFromCSharp ,它继承自 C #类 CSharpClass , ExtendsFromCSharp 类提供一个 Add(x,y) 方法,将两数相加,用 UML 表示如图 4 :


图 4 从 C# 类继承而来的 VB 类

具体代码如下:

Imports CSharpClassNameSpace.CSharpClass

' 继承自 C #组件中的类 CSharpClass

Public Class ExtendsFromCSharp

Inherits CSharpClassNameSpace.CSharpClass

Public Function Add( ByVal x As Integer , ByVal y As Integer ) As Long

Return x + y

End Function

End Class

编译生成 VBComponent.DLL 组件(至于如何使用和测试这个类,就不用我多说了吧?)。

现在, VBComponent 组件中的 ExtendsFromCSharp 类将拥有两个方法: SaySomething 来自 C# 基类 CSharpClass ,而 Add() 函数则由 VB 实现。你创建的 ExtendsFromCSharp 类对象居然组合了两种不同语言开发的功能,你甚至不知道这些方法和函数是由哪种语言开发的,是不是很神奇?

让我们稍微休息一会,进行一个小结:

* 现在我们已掌握了从现成的组件中派生新类的方法,这就是说,我们可以建立自己的组件库,并在合适的时候动态地扩展它,这种扩展是跨语言的。

* 在 VS.NET 中使用混合语言组件时,当所使用的组件修改过后,注意需要动态地更新工程引用。方法是重新生成解决方案,或者是删除原有引用后再重新加入工程。

* 由于组件间相互继承,这就造成了组件库之间的依赖性(比如 VBComponent.DLL 组件就依赖于 CSharpClass.DLL ),因此,在实际项目开发中,任何一个项目小组成员所开发的组件库,都要求在文档中声明其组件库依赖性。另外,在系统开发完成部署到用户计算机上时,相互依赖的组件库必须绑在一起同时复制到用户计算机上,不能只提供一个。

下面,让我们走得更远一些,在组件间实现多态!

组件间的多态调用

我们来实现一个“经典”的多态例子,它说明以下事实:圆和矩形都是几何图形,都可以求面积。

继续上面的例子,在 C# 工程中选定原先的 CSharpClass.cs 文件,在类 CSharpClass 之外,输入以下代码:

public interface IMyShape

{

double Area();

}

public class CSharpRect :IMyShape

{

public float width;

public float height;

public double Area()

{

return width*height;

}

}

很明显,在这里我们定义了一个接口 IMyShape ,类 CSharpRect 实现了这个接口,它对接口所定义的求面积的函数 double Area() 提供了自己的实现:

** 矩形面积 = 长 * 宽 **

编译生成解决方案, CSharpClass.DLL 得到更新。

打开 VBComponent 工程,注意到刷新此工程对 CSharpClass.DLl 的引用,检查方法是在选菜单:视图 à 对象浏览器,查看 CSharpClass 是否体现了新的更改,如 5 图所示:

图 5 检查组件是否更新

新建一个类文件 VBCircle.vb ,输入以下代码:

Public Class VBCircle

Implements CSharpClassNameSpace.IMyShape

Private _radius As Single

Property Radius() As Single

Get

Radius = _radius

End Get

Set ( ByVal Value As Single )

_radius = Value

End Set

End Property

Public Sub New ()

_radius = 0

End Sub

Public Function Area() As Double Implements CSharpClassNameSpace.IMyShape.Area

Return System.Math.PI * _radius * _radius

End Function

End Class

编译,生成 VBComponent.DLL 。

现在,我们就实现了基于组件的以下面向对象系统设计:

新建一个使用 VB 的 Windows 应用程序,在工程中加入对以上两个组件库的引用,往窗体上加入一个按钮,在其 Click 事件中书写以下代码:

Private Sub Button_Click( … ) Handles Button6.Click

Dim VBObj As New VBComponent.VBCircle()

VBObj.Radius =10

Dim CSharpObj As New CSharpClassNameSpace.CSharpRect()

Dim area As Double

CSharpObj.width = 10

CSharpObj.height = 20

CalArea(VBObj)

CalArea(CSharpObj)

End Sub

其中 CalArea() 是一个 Sub 过程,它接收一个 IMyShape 类型的参数,可以传给它任何一个实现了 IMyShape 接口的对象,这种以接口而不是具体类来编定代码的方法,就是典型的多态编码方式。

Private Sub CalArea( ByVal obj As CSharpClassNameSpace.IMyShape)

MessageBox.Show(Convert.ToString(obj.Area()))

End Sub

经过测试,跨语言、跨组件的多态的确可以正常地动作。

好了,现在让我们好好想想都实现了什么东西,可以怎样应用到开发实践中:

我们可以将某个接口封装到一个组件中,然后,具体实现这个接口的类我们可以放到不同的组件中,交给不同的程序员以他们所喜爱的语言来开发。使用这些组件的程序员只要在他的代码中始终使用接口变量而不是具体类的变量,我们就可以动态地替换掉某个具体的实现接口的组件,而不会影响使用这些组件的程序。

哇,这不就意味着我们可以把一个完整的软件系统给大卸八块,然后根据具体情况选一个组件插入系统?太棒了!下面,就让我们来开始进行组件化编程最精彩之旅 --- 软件组件的动态装配与插拔。

Published At
Categories with Web编程
Tagged with
comments powered by Disqus