书城计算机网络综合应用软件设计
8724600000023

第23章 软件构造(2)

一旦定义了一个对象的特性,则有必要决定这些特性的可见性,即哪些特性对外部世界是可见的,哪些特性用于表示内部状态。在这个阶段定义对象的接口。通常,应禁止直接访问一个对象的实际表示,而应通过操作接口访问对象,这称为信息隐藏。事实上,信息隐藏是用户对封装性的认识,封装则为信息隐藏提供支持。封装保证了模块具有较好的独立性,使得程序维护修改较为容易。对应用程序的修改仅限于类的内部,因而可以将应用程序修改带来的影响减少到最低限度。

4.多态性

多态性是指允许不同类的对象对同一消息作出响应。比如同样的加法,把两个时间加在一起和把两个整数加在一起肯定完全不同。又比如,同样的选择编辑—粘贴操作,在文字处理程序和绘图程序中有不同的效果。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好地解决了应用程序函数同名问题。

6.3.2面向对象的开发的优点

面向对象开发时间短,效率高,可靠性高,所开发的程序更强壮。由于面向对象编程的可重用性,可以在应用程序中大量采用成熟的类库,从而缩短了开发时间。

应用程序更易于维护、更新和升级。继承和封装使得应用程序的修改带来的影响更加局部化。

可扩充性:面向对象编程从本质上支持扩充性。如果有一个具有某种功能的类,就可以很快地扩充这个类,创建一个具有扩充功能的类。

代码重用:由于功能是被封装在类中的,并且类是作为一个独立实体而存在的,提供一个类库就非常简单了。事实上,任何一个.NET Framework编程语言的程序员都可以使用.NET Framework类库,.NET Framework类库提供了很多的功能。而且我们可以通过提供符合需求的类来扩充这些功能。

6.3.3如何使用名称空间

名称空间的概念是.NET框架中重要的概念,因为它可以决定哪个类可以被组成逻辑组的机制,并且使得这些类更容易的搜索及管理。在Namespace...EndNamespace块之间声明的任何类、结构等将可以使用那个名称空间被寻址,在VB.NET中名称空间是使用块结构来声明的。例如:

Namespace Name Space A

Public Class Class One

End Class

End Namespace

类可以使用这个名称空间来引用,这样定义一个变量就变成了:

Private obj As Name SpaceA.Class One

因为名称空间是使用块结构来创建的,所以在单一的源文件中就不仅可以包含多个类,而且可以包含多个名称空间。同样,在相同名称空间的类可以被创建在分隔的文件中。换句话说,在一个VB.NET工程中,我们可以使用在不同源文件中相同的名称空间,而所有在这些名称空间中的类将是那个相同名称空间的一部分。

为了更好地理解,下面再给出一个源文件:

Namespace Name Space A

Public Class Class One

End Class

End Namespace

在工程中还有以下一个独立的源文件,其代码如下:

Namespace Name Space A

Public Class Class Two

End Class

End Namespace

以上的两段代码是为了说明在同一个名称空间NameSpaceA中有两个类:ClassOne和ClassTwo。

这里还需指出,在默认状态下,VB.NET工程有一个默认的根名空间(root namespace),它实际上是工程属性的一部分。这个根名空间使用了与工程相同的名字。所以当使用名称空间块结构的时候,实际上是增加到根名空间上去。因此,如果工程命名为MyProject,那么可以这样来定义一个变量:

Private obj As My Project.My Namespace.Class One

在.NET开发中,.NET Framework类库就是这样组织的,其中有80多个名字空间,经常使用的名字空间包括System、System.IO、System.Drawing、System.Windows.Forms等。

如果要在程序中使用名字空间,可以首先导入它,以便在以后每次使用其成员时无须重复该名字空间的名字。例如,导入名字空间System可以使用这个名称空间中的Console方法。

Imports System

Class Person

Dim salary As integer=10

Dim yearlyBonus As integer=10

Public Sub PrintSalary()

Console.Write(salary)

End Sub

Public Shared Sub Main()

Dim person As Person

person=New Person()

person.PrintSalary()

End Sub

End Class

还可以在不同的名字空间中拥有相同名字的类。要正确地使用一个类,通常的做法是在一个类的前面使用名字空间的名字。例如,可以以System.Console的方式使用System名字空间中的Console类。

6.3.4面向对象的实现

1.如何使用类

在面向对象编程技术中,类是重点中的重点。简单地说,类是一种提供一定功能的数据类型。在VB.NET中定义一个类要用到关键字Class。以下定义了一个Person类:

Class Person

End Class

类里面还可以定义自己的属性和方法。

2.如何创建属性

在类中创建属性比较简单。

Private Myname As String

Public Property Name()As String

Get

Return Myname

End Get

Set

Myname=Value

End Set

3.如何创建类方法

一个类有象域、属性、子程序和函数等成员。例如,下面的Person类中有一个名字为DoSomething的方法。

包含DoSomething方法的Person类。

Class Person

Public Sub DoSomething()

End Sub

End Class

子程序和函数都被称为方法。

另一种类成员是成员变量。下面的代码定义了含有salary和quarterlyBonus两个成员变量的Person类,并给出了一个简单的应用实例:

Class Person

Dim salary As integer=10

Dim yearlyBonus As integer=10

Public Sub PrintSalary()

System.Console.Write(salary)

End Sub

End Class

Module Module1

Public Sub Main()

Dim aperson As Person

aperson=New Person()

aperson.PrintSalary()

End Sub

End Module

上述代码段中的Module1模块中提供了子程序的Main函数,这也是VB.NET程序开始的地方。要编译源程序,就必须用一种或另一种方式提供访问MainSub的途径。

如果使用的不是VisualStudio.NET,那么可以使用vbc.exe软件编译VB.NET源程序,vbc.exe是在安装.NET Framework时自动安装的。例如,当把源代码保存为Person.vb文件后,在Person.vb所在的目录下,输入vbcPerson.vb即可编译该源程序。

现在再来看看上面的代码,子程序的Main函数首先定义了一个Person类型的变量aperson,

Dim aperson As Person

然后使用关键词New对Person进行初始化,

aperson=New Person()

这样,就得到了一个Person类型的变量,然后就可以使用它的功能了。在例子中,可以使用下面的方法调用PrintSalary方法,

aperson.PrintSalary()

这一方法会打印Person中salary变量的值。

当然,也可以将子程序的Main函数移到类的定义中去,这样就无须再使用模块了。下面的代码即演示了这种方法:

子程序的Main函数在类的定义中

Class Person

Dim salary As integer=10

Dim yearlyBonus As integer=10

Public Sub PrintSalary()

System.Console.Write(salary)

End Sub

Public Shared Sub Main()

Dim person As Person

person=New Person()

person. PrintSalary()

End Sub

End Class

4.如何使用重载方法

VB.NET的另外一个新特性是有重载方法的能力。重载的意思是,只要每一次的声明都有不同的参数列表,就可以在一个类中多次声明相同名字的方法。不同的参数列表意味着在列表中不同类型的数据类型。假如在刚才的Person类中方法printSalary要根据不同的参数类型来进行打印工资。以下可以定义:

public overloads sub PrintSalary(byval name as String)

dosomething()

end sub

public overloads sub printSalary( byval name as string)

doSomething()

end sub

仔细观察可以发现,两种方法的声明都是有相同的方法名字。这一点在VB6.0中就是不行的,它要求每一个方法名字都不一样。但是,在VB.NET中就允许存在相同名字的方法,但其参数要求是不同的。值得一提的是,每一个声明都要加入Overloads关键字。当重载一个方法的时候,可以使用Public、Friend等辖域关键字让它有不同的作用域,具体做法只要使用不同的参数列表即可。重载是多态的一种形式。

5.如何进行构造和析构

对象构造是在创建一个类实例的时候触发的。具体可以使用关键字NEW来实现它。这个构造函数有完整的错误处理能力并可以接收参数。所以可以在创建对象的时候来对它们进行初始化,这是VB.NET一个十分重要的特性。VB.NET中构造函数方法是SubNew。

Public Class Person

Public Sub New()

(在这里初始化对象)

End Sub

End Class

利用这种类型的构造函数,可以如下创建类的实例:

Dim obj As New Person()

但是,在创建对象的时候往往要用数据来初始化对象。可以从数据库中来装载一些数据,或者可以直接为对象提供数据。不管用什么方法,都是想在对象被创建的时候为它提供一些数据。为了做到这点,可以增加参数列表给New方法:

Public Class Person

Public Sub New(ByVal Name As String)

Myname=name

End Sub

End Class

现在来创建类的一个实例,并且为对象提供数据,代码如下:

Dim obj As New Person(”张飞”)

为了增加灵活性,可以接收可选的参数数值。可以有两种实现方法:通过使用Optional关键字来声明一个可选择的参数,或者通过重载New方法。为了使用Optional关键字,简单地声明可选择的参数,代码如下:

Public Sub New(Optional ByVal name As String=””)

If name=””Then

(这里可以初始化对象)

Else

’这里用姓名进行初始化

Myname=name

End If

End Sub

但是这种方法太过于理想化了,因为不得不检查参数是否已经提供,然后决定怎样初始化对象。New方法有两个路径可以实现。第一种是对于每种行为类型而言的,它可以通过重载来实现:

Public Overloads Sub New()

(这里可以初始化对象)

End Sub

Public Overloads Sub New(ByVal name As String)

(这里可以使用name数值来初始化对象)

End Sub