VB.NET面向对象的程序设计语言
新版的Visual Basic 7也就是Visual Basic.NET,具有了面向对象语言的所有特征。即使以老vb程序员的角度看也对象的慨念并不完全是新的,但也要尽可能用面向对象的方式写代码。
如果你问一个面向对象程序设计高手什么是面向对象程序设计语言?那么你可能将听到几个绝对少不了的单词,比如:类、接口、消息隐匿、封装、继承、多态等等。作为一个话题,面向对象语言不是那种很简单只需要一两天就能精通或者仅仅靠一次演讲就能掌握的语言。要掌握面向对象程序语言你需要作在掌握理论的同时还要做大量的练习。本文表述了在vb.NET中运用面向对象原理编程的基本方法,本文没有全面涉及vb.NET面向对象编程,本文仅仅是一个开始。
面向对象编程的优点
你是否对现代程序设计语言如此倾向面向对象编程感到惊讶?这有几个原因,c++作为c的一个扩展发展起来支持面向对象编程技术,还有java这个星球上最受欢迎的编程语言也是一种面向对象的编程语言,然后,的确如此,vb发展成vb.NET后,也成为一种完全的面向对象的编程语言。有几个好的原因导致了这个转变。面向对象编程有几个优点,比如:易于进行代码维护,可扩展性好,代码重用技术。这些优点是过程编程所没有的。下面就谈谈面向对象技术的这些优点:
易于维护
在面向对象编程中模块性是与生俱来的,实体表现为类和名字空间中具有相同功能的类,你可以向名字空间中增加一个类却不会影响名字空间的其他成员。
可扩展性
面向对象编程支持扩展性,如果你有一个有某种功能的类,你可以很快的扩展这个类,创建另一个具有扩展功能的类。
代码重用
自从功能被压缩到一个类中并且类作为一个独立的实体存在,提供一个类库就变得非常容易了,事实是任何一个.NET Framework程序员都可以使用.NET Framework类库,.NET Framework类库是一个有丰富类的类库,提供很强的功能,更可贵的是你可以很容易的扩展这些功能来满足你的需要。
现在我们看看面向对象编程的特征的使用,首先从最简单的开始。
类
在面向对象编程技术中类是主要的焦点,简单的说,类是一种提供功能的数据类型。在vb.NET中宣布一个类要使用关键字class,比如,list1中就宣布了一个叫employee的类。
Listing 1:Employee类
Class Employee
End Class
这是一个非常简单的类。注意微软推荐使用Pascal语言对类的命名规则。这就意味着类名的第一个字母必须是大写,并且后来的并发连结词的第个字母均为大写。一个好的类名应该象这样的GeneralManager, SmallDictionary, StringUtil。
类成员
一个类有象域、属性、子程序和函数那样的成员,比如,list2中employee类中有一个叫work的子程序
Listing 2:
Class Employee
Public Sub Work ()
' Do something here
End Sub
End Class
子程序和函数又叫方法,方法的命名也遵循Pascal命名法。
另一个类成员类型是域,域的命名法则遵循camel-case法则,如一个好的域命名象salary 和quarterlyBonus这样,在list3中我们在Employee类中添加了两个域salary和quarterlyBonus
Class Employee
Dim salary As Decimal = 40000
Dim yearlyBonus As Decimal = 4000
Public Sub PrintSalary()
' print the salary to the Console
System.Console.Write(salary)
End Sub
End Class
对象实例
一个类是一个模板或代表实体的蓝图。由于要使用类的域、方法或其他成员,你第一次需要将类的观念转变为对象,这样说吧,仅仅是跑车的蓝图是没有用的,除非工程师将蓝图造成车,从另一个方面说,你驾驶的是车而不是蓝图。
在面向对象编程中,对象被称为类的实例,因此创建一个对象的过程又被称为实例化。
list4示范了实例化employee类
Listing 4: 对象初始化
Class Employee
Dim salary As Decimal = 40000
Dim yearlyBonus As Decimal = 4000
Public Sub PrintSalary()
' print the salary to the Console
System.Console.Write(salary)
End Sub
End Class
Module Module1
Public Sub Main()
Dim anEmployee As Employee
anEmployee = New Employee()
anEmployee.PrintSalary()
End Sub
End Module
Listing 4中的模块Module1中提供了Main sub,在vb.NET程序中Main Sub是整个程序的入口,要编译源程序,那么你就必须提供访问Main Sub的途径。
如果你没有使用Visual Studio.NET,那么可以使用vbc.exe 编译vb.NET源程序,vbc.exe 是在安装.NET Framework时自动安装的。举个例子,当你把源代码保存到文件Employee.vb中后,在Employee.vb相同的目录下输入vbc Employee.vb。
现在我们回到list4的代码中,在Main sub中声明了Employee类的对象变量,这个变量叫anEmployee.
Dim anEmployee As Employee
anEmployee初始化Employeer时必须使用关键字new.
anEmployee = New Employee()
现在我们有一个Employeer的对象,你可以使用它的功能了。在我们的例子中,调用了PrintSalary 方法。
anEmployee.PrintSalary()
你也可以把Main Sub放在类中,采用这种方法就不需要模块,如list5中所示
Listing 5: Moving the Main sub to the class itself
Class Employee
Dim salary As Decimal = 40000
Dim yearlyBonus As Decimal = 4000
Public Sub PrintSalary()
' print the salary to the Console
System.Console.Write(salary)
End Sub
Public Shared Sub Main()
Dim employee As Employee
employee = New Employee()
employee.PrintSalary()
End Sub
End Class
注意在PrintSalary 方法中调用了System.Console.Write意味着调用了Console类的write方法并且Console类是System名字空间的一部分,关于名字空间我们将在后面讲述。
名字空间
当写.NET应用程序时,需要写类和其他数据类型。为使应用程序更有条理,组织性更好,需要将他们聚合进名字空间中,这也是微软用.NET Framework类库的原因。微软.NET Framework sdk文档中的.NET Framework类库中包含了80多个名字空间,包括常用的重要的名字空间,如System, System.IO, System.Drawing, System.Windows.Forms等等。举例而言,在Employee类中的PrintSalary 方法,我们使用了system名字空间中的console类。
如果在程序中要经常使用一个名字空间,可以采取引用该名字空间的方法,这样在每次调用其成员时就用不作重复写名字空间了。例如你可以象下面这样改写list4和list5。
Listing 6: Importing a namespace
Imports System
Class Employee
Dim salary As Decimal = 40000
Dim yearlyBonus As Decimal = 4000
Public Sub PrintSalary()
' print the salary to the Console
Console.Write(salary)
End Sub
Public Shared Sub Main()
Dim employee As Employee
employee = New Employee()
employee.PrintSalary()
End Sub
End Class
现在你可以在PrintSalary方法中使用名字空间而不用提及名字空间,因为名字空间已经引用了。
在不同的名字空间允许有相同名字的类,正确地引用一个类最普通的实践是提到过的在类名前面的名字空间。如system名字空间中的Console的引用方法是:System.Console。
访问类型
在很多例子中,当你写出一个类后,你要将类提供给其他人访问并且使用它的功能,他们可调用这个类的方法或者访问类的域。面向对象编程的一大好处是可以对类成员的访问进行限制。这就意味作,你能够完全控制想显示的内容。
你可以让其他程序员访问类中的方法,也可以不让其他程序访问,除非是来自类的内部。
在vb.NET中有几个级别的访问控制,详细请看下表:
Public Public类成员没有访问限制。构造public类成员是在类成员名前面使用关键字public,所有人均可访问public成员。例如,Employee类中的PrintSalary方法是一个公有方法,能够被任何人和函数调用。PrivatePrivate类成员只能被类内部访问,使用Private关键字声明私有化类成员。Protected保护成员能被类内部成员和他的继承类访问,使用关键字Protected定义保护成员。Friend 友员访问限制在声明该类的程序中,使用关键字Friend声明一个友员。Protected friendprotected和friend的结合。在面向对象编程中不同的访问限制提供了不同的信息隐藏方式,从另外一个方面来说,你可以保护你不想显示的类成员变量。
静态成员
我们再看一次list4,list5,list6中的Employee类,你可能会感到惊奇为什么我们在使用System.Console的write方法前没有实例化这个类?这是因为在面向对象语言中有一种特殊的成员类型--静态成员,在vb.NET中术语share与c++中的static有相同作用。
静态意味作成员可以使用而用不作实例化,例如,在list7中SalaryLevel类提供了静态域。
Listing 7:
Class SalaryLevel
Public Shared Level1 As Decimal = 35000
Public Shared Level2 As Decimal = 40000
Public Shared Level3 As Decimal = 45000
Public Shared Level4 As Decimal = 50000
Public Shared Level5 As Decimal = 55000
Public Shared Level6 As Decimal = 60000
Public Shared Level7 As Decimal = 65000
Public Shared Level8 As Decimal = 70000
Public Shared Level9 As Decimal = 75000
Public Shared Level10 As Decimal = 80000
End Class
那么我们可以在程序中使用这个类,如list8
Listing 8: 使用类的静态成员
Imports System
Class SalaryLevel
Public Shared Level1 As Decimal = 35000
Public Shared Level2 As Decimal = 40000
Public Shared Level3 As Decimal = 45000
Public Shared Level4 As Decimal = 50000
Public Shared Level5 As Decimal = 55000
Public Shared Level6 As Decimal = 60000
Public Shared Level7 As Decimal = 65000
Public Shared Level8 As Decimal = 70000
Public Shared Level9 As Decimal = 75000
Public Shared Level10 As Decimal = 80000
End Class
Class Employee
Dim yearlyBonus As Decimal = 4000
Public Sub PrintSalary()
' print the salary to the Console, use
' the static field of SalaryLevel
Console.Write(SalaryLevel.Level4)
End Sub
Public Shared Sub Main()
Dim employee As Employee
employee = New Employee()
employee.PrintSalary()
End Sub
End Class
在Employee类的PrintSalary方法中,我们没有创建SalaryLevel类的对象就使用了SalaryLevel的静态域Level4 。类中非静态成员称为实例成员。
构造器
构造器是一种特殊的方法,在类初始化时必须使用构造器。在vb.NET中称为new方法,但是正如你看到的,在前面的代码中没有一个new方法,是的,在没有出现构造器时,vb.NET将为你创建一个。当你使用new关键字初始化一个对象时,类构造器被调用。当初始化对象时,你能够提供初始化代码以保证对象运行。
如果使用了关键字new,调用了类构造器,vb.NET将不再为你创造一个。
继承
继承是一个这样的特征即允许你扩展类,如果你需要一些功能,你可以创造一个新类,如果你需要的功能中的部分功能已经能由一个已经存在的类提供了,你可以扩展原来的那个类来构建一个新类。那么你新建的这个类成为子类或者继承类,原来的那个类称为父类或者基类。扩充类的过程称为扩展,有时术语subclass或inherit 用于描述扩展类的行为。在vb.NET中一个类只能有一个父类,多个父类的情况是不允许的。
在语法构成上,声明一个扩展类在类名后面使用分号,分号后面使用Inherits和父类名,例如,扩展类Employee创建一个新类Manager,代码如下
Listing 9: Extending a class
Imports System
Class Employee
Dim salary As Decimal = 40000
Dim yearlyBonus As Decimal = 4000
Public Sub PrintSalary()
' print the salary to the Console
Console.Write(salary)
End Sub
End Class
Class Manager: Inherits Employee
End Class
如果单词Inherits 显示在下一行,那么就不需要分号,如:
Class Manager
Inherits Employee
End Class
现在你可以初始化一个Manager对象,使用Manager对象中的成员,如下面的代码
Listing 10: 初始化Manager对象
Class Employee
Public salary As Decimal = 40000
Public yearlyBonus As Decimal = 4000
Public Sub PrintSalary()
' print the salary to the Console
Console.Write(salary)
End Sub
End Class
Class Manager: Inherits Employee
End Class
Module Module1
Public Sub Main()
Dim manager As Manager
manager = New Manager()
manager.PrintSalary()
End Sub
End Module
下面的例子中显示了在manage类中添加一个新方法PrintBonus
Listing 11: Adding a method to the derived class
Class Manager: Inherits Employee
Public Sub PrintBonus()
Console.Write(yearlyBonus)
End Sub
End Class
注意成员访问限制的使用,比如说如果设定yearlyBonus域为私有,那么manage类就不能访问他,否则在编译时就会得出错误结论。
继承只是一个普通的实践。事实上,.NET Framework类库由不同层次的类组成,他们分别继承于其他的类。比如,Windows.Forms名字空间中的button类是ButtonBase类的子类,而ButtonBase类本身又是Control类的子类,所有类最终都以System.Object作为他们的根,在.NET Framework类库中System.Object又称为根或者超类。
list12示范了继承强大的能力。
Listing 12: Extending System.Windows.Forms.Form
Public Class MyForm : Inherits System.Windows.Forms.Form
End Class
声明的这个空白类,经编译执行后生成一个windows表单,你一行代码都用不作写就可以创建一个表单,这是因为myform继承于System.Windows.Forms.Form,他也继承了form的功能。
NotInheritable类
要使你的类不能够被继承,可以使用关键字NotInheritable。例如list13中的类Calculator就不能被继承
Listing 13:
NotInheritable Class Calculator
End Class
如果试图扩展这个类将产生一个编译错误,那么既然继承有这么大的好处,为什么要让类不能被继承呢?其中一个原因是你不想让你的类被其他人扩展,另外一个原因是继承类产生了更快的代码。无论如何你应该谨慎的使用继承类,因为它可能导致面向对象编程的主要目的的失败。
还有一种类叫final类,他和其他面向对象语言中的final类相同。
结论
vb.NET支持众多的面向对象的特征,本文显示了vb.NET的不同特征,并提供了13个例子,可以以此开始学习vb.NET。
[责任编辑:editor]