中超

VB.NET面向对象的实现(3)继承

2019-09-11 12:25:00来源:励志吧0次阅读

继承

本教程设计的内容有:基本的继承、阻止继承、继承与辖域、保护方法、重载方法、重载与构造方法、创建基类以及抽象方法。

当VB面向对象特性变得越来越强大的时候,我们会发觉VB缺少了继承的内容。继承是类为了得到父界面或者现有父类的一种能力。当创建一个新的从父界面或者现有父类继承而来的类的时候,我们就为原来的类创建了一个子类。这就是我们所知的父子关系。

现有许多关于继承的术语,但是很多是多余的。原来的类,即我们所继承的界面和行为可以由以下的几种互换的说法:

Parent class (父类)

Superclass (超级类)

Base class (基类)

而由原来的类继承而来的界面或者行为也有以下的几种互换的说法:

Child class (子类)

Subclass (次类)

继承是用于生物学上的名词。比如,狗是犬科动物而犬科动物又是哺乳动物,因此作为犬科动物,狗继承了哺乳动物所有的属性和行为,这就是继承的原始涵义,即生物学上的继承。在这里借用继承这个名词用于面向对象中,具有许多相似之处。

为了在VB中满足许多程序设计人员能够象在Visual C++中利用面向对象的功能,特别是继承的功能,VB.NET开始有了继承的概念。但是VB.NET还是不允许多重继承,即子类不能有多个父类继承而来,它只能继承一个父类。而VB.NET允许深度的继承分级结构,即一个子类可以有另外一个子类继承而来;但是VB.NET还是不允许同时继承多个父类。

在父子关系中,父对象可以拥有多个子对象,而子对象虽然都是由父对象继承而来但是它们是不同类型的。举个例子,一群子女虽然都是由父母生育的,但是他们还是有不同的相貌、性格等等。

接下来我们详细介绍VB.NET的继承。

实现基本的继承

为了探讨继承,我们先考虑以下一个商业的例子:每一个定货都有一个线路项,可能有产品线路项和服务线路项。这两种线路项是有些不同的。但是当我们在分开实现ProductLine和ServiceLine类的时候,我们就会发现其实它们有许多相同之处。如果分开编写这两个类的代码,不仅编程效率低,而且程序代码也难以维护,所以最好的方法就是使用它们一些相同的代码。

为了实现使用相同的代码,继承就起了很大的作用了。使用继承,我们可以创建一个LineItem类(父类),它包含了所有的共用代码。然后我们再创建ProductLine和ServiceLine子类,这两个类是由LineItem继承而来的。这样它们就可以自动地获得所有的共用代码了。

假如LineItem类为:

Public Class LineItem

Private mintID As Integer

Private mstrItem As String

Private msngPrice As Single

Private mintQuantity As Integer

Public Property ID() As Integer

Get

Return mintID

End Get

Set

mintID = value

End Set

End Property

Public Property Item() As String

Get

Return mstrItem

End Get

Set

mstrItem = Value

End Set

End Property

Public Property Price() As Single

Get

Return msngPrice

End Get

Set

msngPrice = Value

End Set

End Property

Public Property Quantity() As Integer

Get

Return mintQuantity

End Get

Set

mintQuantity = Value

End Set

End Property

Public Function Amount() As Single

Return mintQuantity * msngPrice

End Function

End Class

这个类中有所有的共用代码以及一些基本的数据区域和用于计算项目价钱的方法。

如果线路项对于产品而言,我们则需要再增加一些代码。这个项目的数值应该要验证一下确保它指一个实际的产品,并且可能的话我们也想提供产品的描述,所以ProductLine类的代码如下:

Public Class ProductLine

Inherits LineItem

Private mstrDescription As String

Public ReadOnly Property Description() As String

Get

Return mstrDescription

End Get

End Property

Public Sub New(ByVal ProductID As String)

Item = ProductID

(此处你可以从数据库中转载产品数据)

End Sub

End Class

上面语句中我们已经使用的继承语句:

Inherits LineItem

这条语句使ProductLine类获得了LineItem类的所有的界面元素或者行为。所以我们可以如下编写客户代码:

Protected Sub Button1_Click(ByVal sender As Object, _

ByVal e As System.EventArgs)

Dim pl As ProductLine

pl = New ProductLine(23abc

MessageBox.Show(pl.Item)

MessageBox.Show(pl.Description)

End Sub

以上的代码使用了从LineItem类继承而来的Item属性以及ProductLine中的Description属性。

类似地,我们可以编写ServiceLine:

Public Class ServiceLine

Inherits LineItem

Private mdtDateProvided As Date

Public Sub New()

Quantity = 1

End Sub

Public Property DateProvided() As Date

Get

Return mdtDateProvided

End Get

Set

mdtDateProvided = Value

End Set

End Property

End Class

这里要注意的是,上面的继承语句表明ServiceLine是LineItem的子类。而DateProvided属性是从LineItem类中加入的界面。

[下一页]

阻止继承

在缺省状态下,我们创建的任何类都是作为一个基类使用的,而其它的类是有这个基类创建而来的。有时当我们想创建一个类,而这个子类不能被继承。为了做到这一点,我们可以在类的声明中使用NotInheritable关键字。

Public NotInheritable Class ProductLine

End Class

当使用了这个关键字,其它代码都不能使用Inherits关键字来创建一个由这个类继承而来的子类。

继承和辖域

当我们通过继承来创建一个子类的时候,新类就可以从父类中得到了所有的Public(公共)和Friend(友)方法、属性和变量。如果你在父类中声明一个Private(私有)的方法、属性和变量,那么在新的子类中就不能得到这个类的方法、属性和变量。

当然也有个例外,就是New方法。构造函数方法必须在每一个子类中重新编写。这个内容我们在本教程的后面将深入讨论。

举个例子,我们可能从LineItem类中重写Amount方法,具体如下:

Public Function Amount() As Single

Return CalcAmount

End Function

Private Function CalcAmount() As Single

Return fQuantity * fPrice

End Function

从这个改变中,我们可以看到公共的方法Amount使用了Private方法来工作。

当我们利用LineItem来创建子类ServiceLine的时候,任何的ServiceLine对象都有一个Amount方法,因为它在基类中声明为Public。另外一方面,这个CalcAmount方法被声明为Private,所以所有的ServiceLine类和任何的客户代码都不能访问它。

这里值得一提的是,既然Amount方法存在于LineItem类中,它就可以访问CalcAmount方法即使在ServiceLine类中不能看到这个方法。

举个例子,在我们的客户代码中我们可以这样做:

Protected Sub Button1_Click(ByVal sender As Object, _

ByVal e As System.EventArgs)

Dim sl As ServiceLine

sl = New ServiceLine()

sl.Item = delivery sl.Price = 20

sl.DateProvided = Now

MsgBox(sl.Amount, MsgBoxStyle.Information, amount)

End Sub

结果显示在一个消息框中,这样就阐明了CalcAmount方法被成功调用了,虽然客户代码和ServiceLine代码没有直接调用它。

Protected(保护)方法

有时,Public和Private并不能满足我们的要求。如果我们想声明一些变量或者方法为Private,那么这些变量和方法就只能在我们的类中使用;但是当我们声明一些变量和方法为Public或者Friend,那么这些变量和方法就可以在子类和客户代码中使用。但是,有时有声明一些变量和方法,让它们在子类中有效,而在客户代码中不能用,该怎么办呢?这里可以使用Protected辖域。当变量或者方法被声明为Protected的时候,对于任何类外部的代码将不能调用,但是还是可以被由它继承而来的子类调用。

举个例子吧,如下:

Public Class ParentClass

Protected TheValue As Integer

End Class

Public Class SubClass

Inherits ParentClass

Public Function GetValue() As Integer

Return TheValue

End Function

End Class

在上面的代码中我们有一个父类,它有一个Protected成员变量TheValue。这个变量在任何的客户代码中都不能被调用。但是这个变量对于任何的子类都是有效的因为它继承了这个父类。在这个例子中,SubClass有一个Public方法返回了Protected变量的数值,但是这个变量对于类的外部任何客户代码都是无效的。

小孩咳嗽老不好怎么办
为什么会精神焦虑抑郁消化不良
儿童祛痰药有哪些
宝宝偶尔咳嗽
分享到: