VBNET面向对象的实现(一)_第1页
VBNET面向对象的实现(一)_第2页
VBNET面向对象的实现(一)_第3页
VBNET面向对象的实现(一)_第4页
VBNET面向对象的实现(一)_第5页
已阅读5页,还剩15页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、VB.NET面向对象的实现(一)在VB 6中面向对象的能力还不是很强,但随着VB.NET的出现,其面向对象的能力大大增强。VB.Net不仅为我们提供了新的面向对象的特性,而且它也改变了我们在VB6中实现一些特性时所用的方法。在本教程中我将带你浏览一下这些特性,并将涉及到新的性能以及现有特性的变化。本简缩教程的内容有:1.创建类:类关键字、类及名空间、创建方法、创建属性、重载方法等。2.对象的生命周期:对象的构造、对象的终止3.继承:实现基本的继承、阻止继承、继承与辖域、保护方法、重载方法、重载与构造方法、创建基类以及抽象方法4.共享或类成员:共享方法、共享变量5.事件:共享事件、触发事件6.界

2、面:怎样使用界面7.对象的处理:对象的声明等等8.交叉语言的继承:创建VB.NET的基类、创建C#子类、创建一个客户应用程序。9.可视化继承总结创建类在图1的对话框中用户可以增加任意类型的项目到工程中。在本例子中是使用缺省的项目,即增加一个类模块。不管我们选择了哪种VB 代码文件(如表单、类、模块等等),我们得到文件名字的扩展名都为.vb,如图1中的class1.vb。这里值得指出的是,文件的类型是由它的内容决定的,而不是由文件的扩展名决定的。根据我们所选择的类型,IDE(集成开发环境)就在文件中创建不同的开始代码。在如图1所示的对话框的最后一行给类命名为MyClass,然后点击Open键,这

3、样一个新的文件就将增加到我们的工程中,它包含了以下简单的代码: Public Class MyClassEnd Class在一个.vb文件中可以包含多个类、模块以及其它代码。接下来的设计过程实际上跟VB的差不多,我们可以手动增加其它的代码到这个文件中去。这里值得指出的是一旦在IDE创建类的时候它就会增加一个新的文件到工程中去。类关键字在下面的例子中,代码包含了一个关键字End Class。这是一个新的关键字,使用它的目的是为了在一个源文件中包含多个类,这点正是VB.NET与VB6在创建类区别的精髓所在。每当我们在VB.NET中创建类的时候,我们只是简单地将所有的的代码包含在Class和End

4、Class 之间。例子代码如下: Public Class TheClass Public Sub MyWorks()End Sub End Class 另外在一个特定的源文件(后缀名为.vb)中,我们可以使用多个Class.End Class块。类与名空间名空间的概念是.NET环境重要内容,因为它可以提供哪个类可以被组成逻辑组的机理,并且使得这些类更容易的搜索以及管理。在VB.NET名空间是使用块结构来声明的。例如:Namespace MyNamespace Public Class MyClassEnd ClassEnd Namespace 在Namespace.End Namespace

5、块之间声明的任何类、结构等等将可以使用那个名空间被寻址。在本例子中,我们的类可以使用这个名空间来引用,这样定义一个变量就变成了: Private obj As MyNamespace.MyClass因为名空间是使用块结构来创建的,所以在单一的源文件中就不仅可以包含多个类,而且可以包含多个名空间。同样,在一个相同名空间的类可以被创建在分隔的文件中。换句话说,在一个VB.NET工程中,我们可以使用在不同源文件中相同的名空间,而所有在这些名空间中的类将是那个相同名空间的一部分。为了更好地理解,下面再给出一个源文件:Namespace MyNamespacePublic Class MyClassEn

6、d ClassEnd Namespace我们在工程中还有以下一个独立的源文件,其代码如下:Namespace MyNamespacePublic Class MyOtherClassEnd ClassVB.NET面向对象的实现(二)创建方法在VB.NET中方法的创建还是跟在VB6中的一样,你可以使用Sub或者Function关键字。Sub和Function的区别是:用Sub来创建一个方法,它将不返回数值;若是利用Function来创建一个方法,它将返回一个数值作为结果。例如:Sub MyWorks()End SubFunction MyValue() As IntegerEnd Functio

7、n在VB.NET中我们仍可以使用辖域关键字,这跟在VB 6中的差不多,只是多了Protected。具体的辖域关键字有:Private表明只能调用类中的代码;Friend 表明可以在我们的工程/组件中调用代码;Public 表明可以在我们的类外部调用代码;Protected是VB.NET新增的,这个我们将在讨论继承的时候再具体阐述。Protected Friend 表明只能在我们的工程/组件调用代码以及我们的Subclass的代码。同样我们将在讨论继承的时候再具体阐述。缺省地,方法的参数是声明为ByVal而不是ByRef。当然,我们仍然可以通过使用ByRef关键字来重载这个缺省的行为。创建属性以

8、前我们创建属性的时候是使用Property Get和Property Let,但现在在VB.NET中已经将它集成到一个结构中去了。例子如下:Private mystrName As StringPublic Property Name() As StringGetReturn mystrNameEnd GetSetmystrName = ValueEnd SetEnd Property缺省的属性在VB6中创建类的时候,我们可以为类声明一个缺省的方法或者属性。具体做法可以菜单选项:Tools(工具)->Procedure Attributes(过程属性)并设置Procedure ID为缺省

9、值。VB.Net用两种方法改变了这种行为。第一,使用一个缺省的关键字来创建缺省的属性,使得声明更加清晰直观。但是,VB.NET还给缺省的属性引入了一种新的限制,即属性必须是一个属性阵列。 属性阵列实际上就跟数组一样,有一个索引。在选择或者列表对象中的项目属性就是一个例子:strText = MyList.Item(5)这个项目属性没有单一的数值,而是有一组的属性,它们可以通过索引来访问。通过使用属性阵列作为缺省属性,我们就允许程序语言避免了在使用缺省属性的多义性。正如我们在VB6中所知道的,关键字Set的限制是关键。下面再看看以下的语句:MyValue = MyObject这句是指对象MyOb

10、ject还是指它的缺省属性呢?为了识别它,在VB6中使用了Set命令来处理对象,如不使用Set就是指缺省的属性。在VB.NET中这条语句是指对象,因为缺省的属性是要被索引的。为了得到缺省的属性,我们要编写以下代码:MyValue = MyObject(5)因为索引是一个清楚的指示器(我们指缺省的属性,而不是MyObject本身),所以就不会有多义的存在了。VB.NET这样的改变就意味着属性阵列过程必须接收一个参数。例如Private MyMoney(100) As StringDefault Public Property Money(ByVal Index As Integer) As St

11、ring GetMoney = MyMoney(index)End GetSetMyMoney(index) = ValueEnd SetEnd Property 最后,看起来这些代码比VB6更清楚,但也会丢失了一些灵活性。在过去,我们喜欢使用缺省的属性。举个例子,我们在用GUI控件的时候经常使用缺省的属性,比如缺省的文本属性。TextBox1 = MyText 但是这在VB.NET中已经不再有效,因为文本属性不再是一个属性阵列,相反地我们必须使用属性名字。重载方法VB.NET的另外一个新特性是有重载方法的能力。重载的意思是我们可以在一个类中多次声明相同名字的方法只要每一次的声明都有不同的参数

12、列表。不同的参数列表意味着在列表中不同类型的数据类型。现在让我们先看看以下的方法声明:Public Sub MyMethod(X As Integer, Y As Integer)这种方法的参数列表可以看成(integer,integer)。为了重载这种方法,我们必须使用不同的参数列表,例如(integer,double)。当然你还可以改变一下数据类型的顺序,比如(integer,double)和(double,integer)是不同的,这两种也是重载。重载不能只是通过改变函数的返回类型来实现,而是要求参数的数据类型不同。作为一个例子,假如我们想提供一个搜索的功能并且根据一些条件返回一组数据,

13、具体代码应该为:Public Function MyFindData(ByVal Name As String) As ArrayList(搜索数据并且返回结果)End Function在VB 6中,如果我们想基于一些条件增加一个新的搜索选项,就必须增加一个不同名字的函数,也就是说VB 6还没有具备重载的能力。但是现在在VB.NET中,我们可以简单地重载已经存在的函数,这一点和Visual C+很是相似。Public Overloads Function FindData(ByVal Name As String) As ArrayList (搜索数据并且返回结果)End FunctionPu

14、blic Overloads Function FindData(ByVal Age As Integer) As ArrayList(搜索数据并且返回结果)End Function 仔细观察可以发现两种方法的声明都是有相同的方法名字。这一点在VB 6中就不行的,它要求每一个方法名字都不一样。但是,在VB.NET中就允许存在相同名字的方法,但其参数要求是不同的。值得一提的是,每一个声明都要加入Overloads关键字。当重载一个方法的时候,我们可以使用Public、Friend等等的辖域关键字让它有不同的作用域,具体做法只要使用不同的参数列表即可。这就意味着我们可以改变MyFindData方法

15、,使它有不同的作用域:Public Overloads Function FindData(ByVal Name As String) As ArrayList (搜索数据并且返回结果)End FunctionFriend Overloads Function FindData(ByVal Age As Integer) As ArrayList (搜索数据并且返回结果)End Function 有了这个改变,在VB.NET工程中其它代码可以使用MyFindData。MyFindData只需要接收一个整型数据作为参数即可。VB.NET面向对象的实现(三)对象的生命周期在VB 6中,对象有一个很

16、清楚的定义以及很容易理解的生命周期的概念,对象的生命周期是由下面的事件来定义的。事件描述Sub Main 运行时它将作为组件被装载,并且是在对象创建之前装载。Class_Initialize 它是在对象中其它代码运行之前运行。当对象被创建的时候它被运行程序所调用。Class_Terminate 是在对象中其它代码运行之后再运行。当对象被卸载的时候被运行程序调用。在VB.NET,对象也有生命周期的概念,但是已经跟以前大不一样了。特别地,我们不再有相同的组件级的Sub Main(它作为一个DLL被装载)的概念,并且Class_Terminate事件也被改变了,而Class_Initialize事件

17、被成熟的构造函数方法所取代。值得指出的是,这个构造函数方法可以接收参数。现在在VB.NET中,我们定义一个生命周期只需要用了一个New事件,这个New事件是在对象中其它代码之前运行的,并且在对象被创建的时候被调用。从VB 6到VB.NET确实变化很大,下面我们具体讨论。构造对象构造是在我们创建一个类新的实例的时候被触发的。具体可以使用关键字NEW来实现它。Sub Main自从VB 6基于COM,创建一个对象将触发一个Sub Main过程运行。这将发生在一个对象从一个给定的组件(通常为DLL)创建来的时候。在创建对象之前,VB 6运行程序将装载DLL(动态连接库)并运行Sub Main过程。.N

18、ET通用语言运行程序处理组件采取不同的方法,当然VB.NET也是这样的。这就意味着没有Sub Main过程在组件装载时候被调用。实际上,Sub Main只使用在当一个应用程序开始的时候。当另外的组件被应用程序装载的时候,只有在类中的代码才被调用。其实在VB6中依靠Sub Main是不明智的做法,因为代码将在所有错误操作之前被运行。Sub Main中的Bugs是难以在VB6中调试。如果我们不得不使用依耐于Sub Main概念的代码来初始化,那么我们需要在VB.NET执行一个工作区。在每一个类中从构造函数方法中调用一个方法是很容易做到的。举个例子,我们可以在一个模块中创建一个有效的代码:Publi

19、c Module CentralCodePrivate blnHasRun As BooleanPublic Sub Initialize()If Not blnHasRun ThenblnHasRun = True(在这里作初始化工作)End IfEnd SubEnd Module这个程序是被设计为只运行一次,不管是怎么被调用。我们可以从类中的每一个构造函数来使用这个方法。比如 :Public Class TheClassPublic Sub New()CentralCode.Initialize()(这里加入另外的工作)End SubEnd Class以上的代码虽然作了一些额外的工作,它跟

20、使用VB6类型的Sub Main程序达到同样的效果。New方法就象Sub Main,Class_Initialize是在其它VB6类中的代码运行之前被调用的。此外,它是在错误处理之前被调用的,所以使得调试变得很难,而错误作为一般的错误显示在客户端来实例化对象。另外地,Class_Initialize不用参数,这意味着在VB6中没有方法可以在对象被创建的时候用数据来进行初始化。 VB.NET剔除了Class_Initialize而采用完整的构造函数方法。这个构造函数有完整的错误处理能力以及可以接收参数。所以我们可以在创建对象的时候来对它们进行初始化,这是VB.NET一个十分重要的特性。VB.NE

21、T中构造函数方法是Sub New。Public Class TheClassPublic Sub New()(在这里初始化对象)End SubEnd Class利用这种类型的构造函数,可以如下创建类的实例:Dim obj As New TheClass()这个例子类似于在Class_Initialize创建一个VB6代码。但是,经常地,我们在创建对象的时候往往要用数据来初始化对象。我们可以从数据库中来装载一些数据,或者我们可以直接为对象提供数据。不管用什么方法,我们是想在对象被创建的时候为它提供一些数据。 为了做到这点,可以增加参数列表给New方法:Public Class TheClass

22、Public Sub New(ByVal ID As Integer) (在这里使用ID数值来初始化对象)End SubEnd Class 现在我们来创建类的一个实例,并且为对象提供数据,代码如下:Dim obj As New TheClass(42)为了增加灵活型,我们可以接收可选的参数数值。为了实现这个,可以有两种方法:通过使用Optional关键字来声明一个可选择的参数,或者通过重载New方法。为了使用Optional关键字,我们简单地声明可选择的参数,代码如下:Public Sub New(Optional ByVal ID As Integer = -1) If ID = -1 Th

23、en(这里可以初始化对象)Else(这里可以使用ID数值来初始化对象)End IfEnd Sub 这种方法太过于理想化了,但是,既然我们不得不检查是否参数是(不是)已经提供,然后决定怎样初始化对象。New方法又两个方法可以实现。第一种是对于每种行为类型而言的,它可以通过重载来实现:Public Overloads Sub New() (这里可以初始化对象)End SubPublic Overloads Sub New(ByVal ID As Integer) (这里可以使用ID数值来初始化对象)End Sub 这种方法不仅可以避免有条件的检查以及简化了代码,而且它还使得对于客户代码对象的使用都

24、变得更清晰。这个重载New方法可以使用参数也可以不用参数,有更大的灵活性。实际上,通过重载,我们可以创建许多不同的构造函数,也可以利用许多种不同的方法来初始化我们的对象。在VB.NET中构造函数方法是可选的。但是只有一个例外,那就是当我们使用继承的时候,父类就只有一个构造函数需要参数。在本教程的后面我们将讨论继承。VB.NET面向对象的实现(四)对象的终止Finalize方法这个垃圾收集机理提供了一些功能,这些功能可以跟VB6中的Class_Terminate事件相媲美。当对象被终止的时候,垃圾收集处理的代码将调用Finalize方法,它就象Class_Terminate一样可以进行一些最后的

25、内存清理工作。Protected Overrides Sub Finalize()(此处可以进行一些内存清理工作)End Sub以上的这些代码可以使用Protected(保护)作用域也可以使用重载关键字。这里值得指出的是,这种方法是在对象被垃圾收集机理终止之前被调用的,所以它跟Class_Terminate很是相似。但是,我们还需要记得这种方法可以在对象被取消引用后被调用,它是通过最后一段客户代码来实现的。实现Dispose方法在有些场合中Finalize方法是不可接收的。如果我们有一个对象,它是使用一些非常有限的宝贵的系统资源,比如数据库连接、文件处理或者系统锁住等等。这时候我们就需要确保系

26、统资源在对象被取消引用的时候是否被释放。 为了实现这个目的,我们可以执行这样一个方法,它可以被客户代码调用来强迫对象被清除并且释放系统资源。虽然这不是一个很好的解决方案,但是它确实是很有效的。习惯上,这个方法就取名为Dispose,其代码如下:Public Sub Dispose()(此处可以进行一些清除工作)End Sub在必要的时候,我们可以调用这个方法来确保内存清除工作的进行。从上面的讨论中,我们可以深刻地体会倒VB6和VB.NET在创建类和对象的一些变化。下一个教程我们将详细讨论一下对象的继承。VB.NET面向对象的实现(五)继承本教程设计的内容有:基本的继承、阻止继承、继承与辖域、保

27、护方法、重载方法、重载与构造方法、创建基类以及抽象方法。当VB面向对象特性变得越来越强大的时候,我们会发觉VB缺少了继承的内容。继承是类为了得到父界面或者现有父类的一种能力。当创建一个新的从父界面或者现有父类继承而来的类的时候,我们就为原来的类创建了一个子类。这就是我们所知的父子关系。现有许多关于继承的术语,但是很多是多余的。原来的类,即我们所继承的界面和行为可以由以下的几种互换的说法:Parent class (父类)Superclass (超级类)Base class (基类) 而由原来的类继承而来的界面或者行为也有以下的几种互换的说法:Child class (子类)Subclass (

28、次类)继承是用于生物学上的名词。比如,狗是犬科动物而犬科动物又是哺乳动物,因此作为犬科动物,狗继承了哺乳动物所有的属性和行为,这就是继承的原始涵义,即生物学上的继承。在这里借用继承这个名词用于面向对象中,具有许多相似之处。为了在VB中满足许多程序设计人员能够象在Visual C+中利用面向对象的功能,特别是继承的功能,VB.NET开始有了继承的概念。但是VB.NET还是不允许多重继承,即子类不能有多个父类继承而来,它只能继承一个父类。而VB.NET允许深度的继承分级结构,即一个子类可以有另外一个子类继承而来;但是VB.NET还是不允许同时继承多个父类。在父子关系中,父对象可以拥有多个子对象,而

29、子对象虽然都是由父对象继承而来但是它们是不同类型的。举个例子,一群子女虽然都是由父母生育的,但是他们还是有不同的相貌、性格等等。接下来我们详细介绍VB.NET的继承。实现基本的继承为了探讨继承,我们先考虑以下一个商业的例子:每一个定货都有一个线路项,可能有产品线路项和服务线路项。这两种线路项是有些不同的。但是当我们在分开实现ProductLine和ServiceLine类的时候,我们就会发现其实它们有许多相同之处。如果分开编写这两个类的代码,不仅编程效率低,而且程序代码也难以维护,所以最好的方法就是使用它们一些相同的代码。为了实现使用相同的代码,继承就起了很大的作用了。使用继承,我们可以创建一

30、个LineItem类(父类),它包含了所有的共用代码。然后我们再创建ProductLine和ServiceLine子类,这两个类是由LineItem继承而来的。这样它们就可以自动地获得所有的共用代码了。假如LineItem类为:Public Class LineItemPrivate mintID As IntegerPrivate mstrItem As StringPrivate msngPrice As SinglePrivate mintQuantity As IntegerPublic Property ID() As IntegerGetReturn mintIDEnd GetSe

31、tmintID = valueEnd SetEnd PropertyPublic Property Item() As StringGetReturn mstrItemEnd GetSetmstrItem = ValueEnd SetEnd PropertyPublic Property Price() As SingleGetReturn msngPriceEnd GetSetmsngPrice = ValueEnd SetEnd PropertyPublic Property Quantity() As IntegerGetReturn mintQuantityEnd GetSetmint

32、Quantity = ValueEnd SetEnd PropertyPublic Function Amount() As SingleReturn mintQuantity * msngPriceEnd FunctionEnd Class这个类中有所有的共用代码以及一些基本的数据区域和用于计算项目价钱的方法。如果线路项对于产品而言,我们则需要再增加一些代码。这个项目的数值应该要验证一下确保它指一个实际的产品,并且可能的话我们也想提供产品的描述,所以ProductLine类的代码如下:Public Class ProductLineInherits LineItemPrivate mstrD

33、escription As StringPublic ReadOnly Property Description() As StringGetReturn mstrDescriptionEnd GetEnd PropertyPublic Sub New(ByVal ProductID As String)Item = ProductID(此处你可以从数据库中转载产品数据)End SubEnd Class上面语句中我们已经使用的继承语句:Inherits LineItem这条语句使ProductLine类获得了LineItem类的所有的界面元素或者行为。所以我们可以如下编写客户代码:Protec

34、ted Sub Button1_Click(ByVal sender As Object, _ByVal e As System.EventArgs)Dim pl As ProductLinepl = New ProductLine(23abcMessageBox.Show(pl.Item)MessageBox.Show(pl.Description)End Sub以上的代码使用了从LineItem类继承而来的Item属性以及ProductLine中的Description属性。类似地,我们可以编写ServiceLine:Public Class ServiceLineInherits Lin

35、eItemPrivate mdtDateProvided As DatePublic Sub New()Quantity = 1End SubPublic Property DateProvided() As DateGetReturn mdtDateProvidedEnd GetSetmdtDateProvided = ValueEnd SetEnd PropertyEnd Class这里要注意的是,上面的继承语句表明ServiceLine是LineItem的子类。而DateProvided属性是从LineItem类中加入的界面。VB.NET面向对象的实现(六)继承阻止继承在缺省状态下,我们

36、创建的任何类都是作为一个基类使用的,而其它的类是有这个基类创建而来的。有时当我们想创建一个类,而这个子类不能被继承。为了做到这一点,我们可以在类的声明中使用NotInheritable关键字。Public NotInheritable Class ProductLineEnd Class当使用了这个关键字,其它代码都不能使用Inherits关键字来创建一个由这个类继承而来的子类。继承和辖域当我们通过继承来创建一个子类的时候,新类就可以从父类中得到了所有的Public(公共)和Friend(友)方法、属性和变量。如果你在父类中声明一个Private(私有)的方法、属性和变量,那么在新的子类中就不

37、能得到这个类的方法、属性和变量。当然也有个例外,就是New方法。构造函数方法必须在每一个子类中重新编写。这个内容我们在本教程的后面将深入讨论。举个例子,我们可能从LineItem类中重写Amount方法,具体如下:Public Function Amount() As Single Return CalcAmount End FunctionPrivate Function CalcAmount() As SingleReturn fQuantity * fPriceEnd Function 从这个改变中,我们可以看到公共的方法Amount使用了Private方法来工作。当我们利用LineIt

38、em来创建子类ServiceLine的时候,任何的ServiceLine对象都有一个Amount方法,因为它在基类中声明为Public。另外一方面,这个CalcAmount方法被声明为Private,所以所有的ServiceLine类和任何的客户代码都不能访问它。这里值得一提的是,既然Amount方法存在于LineItem类中,它就可以访问CalcAmount方法即使在ServiceLine类中不能看到这个方法。举个例子,在我们的客户代码中我们可以这样做:Protected Sub Button1_Click(ByVal sender As Object, _ByVal e As System

39、.EventArgs)Dim sl As ServiceLinesl = New ServiceLine()sl.Item = delivery sl.Price = 20sl.DateProvided = NowMsgBox(sl.Amount, MsgBoxStyle.Information, amount)End Sub结果显示在一个消息框中,这样就阐明了CalcAmount方法被成功调用了,虽然客户代码和ServiceLine代码没有直接调用它。Protected(保护)方法有时,Public和Private并不能满足我们的要求。如果我们想声明一些变量或者方法为Private,那么这些

40、变量和方法就只能在我们的类中使用;但是当我们声明一些变量和方法为Public或者Friend,那么这些变量和方法就可以在子类和客户代码中使用。但是,有时有声明一些变量和方法,让它们在子类中有效,而在客户代码中不能用,该怎么办呢?这里可以使用Protected辖域。当变量或者方法被声明为Protected的时候,对于任何类外部的代码将不能调用,但是还是可以被由它继承而来的子类调用。举个例子吧,如下:Public Class ParentClassProtected TheValue As IntegerEnd ClassPublic Class SubClassInherits ParentCl

41、assPublic Function GetValue() As IntegerReturn TheValueEnd FunctionEnd Class在上面的代码中我们有一个父类,它有一个Protected成员变量TheValue。这个变量在任何的客户代码中都不能被调用。但是这个变量对于任何的子类都是有效的因为它继承了这个父类。在这个例子中,SubClass有一个Public方法返回了Protected变量的数值,但是这个变量对于类的外部任何客户代码都是无效的。VB.NET面向对象的实现(七)共享或类成员随着对象的功能越来越强大,我们有时想访问一些变量、函数或者程序而不需要一个实际的对象实例

42、。在以前,我们可以键入这类型的代码到一个代码模块中,而不管程序是否跟一些类有关。共享方法在VB.NET中我们有了一个较好的改变。不仅一个类可以拥有所有正常的方法和属性(这些方法和属性可以由创建类的实例来实现)而且它们可以拥有一些不需要创建类的实例的方法,这些方法就是本教程要介绍的共享方法。这些方法在其它的编程语言中也称为静态方法或者类方法。一个共享方法不能作为一种普通的方法,通过一个对象的实例来访问,而是可以从类直接访问。下面是共享方法的一个简单的例子:Public Class Math  Shared Function Add(ByVal a As Integer, ByVal b

43、 As Integer) As IntegerReturn a + b  End FunctionEnd Class 我们可以不用实例化一个Math对象,就可以访问,代码如下:Dim result As Integerresult = Math.Add(5, 10)现在请再仔细看看,这里我们不是使用一个变量,而是直接使用类的方法。如果用通常的方法就将导致错误,但是利用了共享方法一切都变得可以接受了。共享方法不仅可以通过通常的方法来访问而且可以在不需要创建一个对象的条件下提供访问的功能。实际上,当一个共享方法被调用的时候,没有任何对象被创建,它就象再模块中的一个程序可以直接被

44、调用。共享方法和其它普通的方法一样也可以被重载,所以可以利用相同的共享方法来创建一系列变化的方法,每一种方法有不同的参数列表。共享方法的缺省的辖域是Public。我们也可以载声明中将共享方法设置为Friend、Protected或者Private。实际上,当重载方法的时候,只要参数列表不同我们就有不同的作用域。究竟共享方法是如何使用的呢,下面我们看看一个例子。当我们想为输入打开一个文本文件的时候,我们可以在File类中使用一个共享代码,如下:Dim infile As StreamReader = File.OpenText(words.txt)Dim strIn As Stringstr =

45、 infile.ReadLine()这里没有任何的类型的文件被创建。OpenText方法是一个共享方法,它打开一个文件并且返回一个StreamReader对象。另外一个例子来自System.Guid数据类型。这个类描述了一个全局的独特的用户ID(GUID)数值,但是我们可以通过一个共享方法来创建一个新的方法。Dim guidID As Guid()guidID = Guid.NewGuid()这个NewGuid方法是直接从Guid类中调用的。它创建了一个新的Guid对象并且返回一个数值。VB.NET面向对象的实现(八)共享或类成员共享变量我们还可以创建另外一种共享成员。有时候类的所有实例需要共

46、享一个数值,有时候每个特定类型的对象要共享相同的变量,这些时候都可以通过使用共享变量来实现目的。一个共享变量可以使用Shared关键字来声明,这一点很象共享方法的声明:Public Class MyCounter  Private Shared mintCount As IntegerEnd Class 跟共享方法一样,我们也可以根据需要来设置共享变量的作用域。在缺省状态下两者就不一样了,共享方法是Public,而共享变量是Private。总而言之,我们要养成一个好的习惯:定义方法和变量的作用域而不使用缺省值,以避免混乱。关于共享变量的一件重要的事情是它们在所有类的实例中都

47、是公用。我们可以键入如下的代码来加强我们的类:Public Class MyCounter  Private Shared mintCount As Integer   Public Sub New()mintCount += 1  End Sub  Public ReadOnly Property Count() As IntegerGetReturn mintCountEnd Get  End Property End Class 仔细看看上面的代码:当我们为类创建了实例时,计数器就增一。+=操作符是一个在VB.NET新有的。在任

48、何时候我们可以通过Count属性来取出count数值。这样,如果我们运行下面的客户代码,我们可以得到结果为3。Protected Sub Button4_Click(ByVal sender As Object, _ByVal e As System.EventArgs)  Dim obj As MyCounter  obj = New MyCounter()  obj = New MyCounter()  obj = New MyCounter()  MsgBox(obj.Count, MsgBoxStyle.Information,coun

49、ter)End Sub如果我们再次运行这段程序,将可以得到6、9等等。只要我们的应用程序继续运行计数器就保持有效,也就是说一旦我们结束应用程序计数器就不再起作用。这项计数对于服务器的处理过程是十分有用的,因为它可以轻松地不停地进行计数。这个数值只有在处理过程重新开始地时候才被复位。全局变量对于共享变量另外一个通常的应用是提供了全局变量的类型。给定一个Public作用域的共享变量: Public Class TheClass  Public Shared MyGlobal As IntegerEnd Class我们可以在客户代码中使用这个变量。TheClass.MyGlobal +=

50、5这个变量将在我们应用程序的任何地方都是有效的,它提供了一个很好的机理来在组件、类、模块等等之间来共享数值。VB.NET面向对象的实现(九)事件在VB.NET中,继承是完全支持事件的。如果一个基类定义了一个Public事件,那么这个事件可以通过基类的代码或者任何由基类继承而来的子类所触发。举个例子吧,我们可以先定义一个基类,代码如下:Public Class Parent  Public Event ParentEvent()  Public Sub DoEvent()RaiseEvent ParentEvent()  End SubEnd Class很显然,类中

51、的代码可以触发ParentEvent事件。我们还可以这样来创建一个子类:Public Class SubClass  Inherits Parent  Public Sub DoSomething()RaiseEvent ParentEvent()  End SubEnd Class这个子类是通过使用Inherits关键字继承而来的,它不仅得到了父类的属性和方法,而且继承了基类的事件。事件可以定义任何的作用域。如果定义为Private事件,那么它就只可以通过发送对象来获得,但是Public事件就可以被任何对象访问。而Protected事件可以通过定义类或者子类来创

52、建对象进行访问。另外Friend 事件可以被VB.NET工程中的任何对象访问。不象方法,事件不能使用Overloads关键字来进行重载。一个类可以使用任何特定的名字来定义一个事件。因为任何子类将自动从父类重得到事件,所有Override关键字就显得没什么作用,故不能用于事件中。共享事件事件可以定义为Shared。共享方法可以触发共享事件,而不能触发非共享事件,具体例子如下:Public Class EventSource  Shared Event SharedEvent()  Public Shared Sub DoShared()RaiseEvent SharedEve

53、nt()  End SubEnd Class一个共享事件也可以由共享方法或者非共享方法来触发,下面是相应的例子:Public Class EventSource   Public Event TheEvent()   Shared Event SharedEvent()  Public Sub DoSomething()RaiseEvent TheEvent()RaiseEvent SharedEvent()  End Sub  Public Shared Sub DoShared()RaiseEvent SharedEvent()End Sub  End Class 如果你想从一个共享方法中触发一个非共享事件就将导致一个语法错误。VB.NET面向对象的实现(十)事件在不同工程之间触发事件在不同工程之间完成触发事件的工作,这在VB中是不能做到的。但是在VB.NET中我们可以使用Event和RaiseEvent关键字并且使用Delegate关键字来实现它。如果你想从VB.NET工程中触发一个事件并且在另外一个工程中收到这个触发,我们就必须使用事件和Delegate的概念。执行远程事件源当我们仍要使用Raise

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论