html5中文学习网

您的位置: 首页 > 网络编程 > ASP.NET » 正文

VB.Net中文教程(4) 类别继承(Inheritance)关系_.NET教程_编程技术

[ ] 已经帮助:人解决问题
继承|教程|中文
1. 类别之继承

类别之间有些互为独立有些具有密切关系。兹介绍类别间常见的关系──「父子」关系由于儿女常继承父母之生理或心理特征所以又称此关系为「继承」(Inheritance) 关系。类别间之密切关系把相关的类别组织起来并且组织程序内之对象。若程序内之对象毫无组织呈现一片散沙就不是好程序。完美之VB程序必须重视类别间之关系对象是有组织的。
如果 A类别「继承」 B类别则称 A为「子类别」(Subclass)也称B 为「父类别」(Superclass)亦即 B为 A之父类别A 为 B之子类别。在 C++中父类别又称为「基础类别」(Base Class)子类别又称为「衍生类别」(Derived Class) 。也许您觉得「继承」之观念很陌生不知如何看出类别间之继承关系。别担心有个简单方法下列两叙述之意义相同──
(1) A 为 B之子类别。
(2) A 为 B之一种(A kind of) 特殊类别。

根据叙述 (2)能轻易找到父子关系。例如肯尼士(Kennex)生产高品质球拍球拍分两种网球拍与羽球拍。从此句子得知网球拍为一种(A kind of) 球拍羽球拍亦为一种球拍。因之网球拍为球拍之子类别羽球拍亦为球拍之子类别亦即球拍是父类别。以下图标之


图1、 基础类别与衍生类别

如果设计程序来记录球拍之生产情形则程序应定义基础类别──球拍以及两衍生类别──网球拍及羽球拍。程序应藉继承关系将三类别组织起来。除了物品(如球拍、汽车等)外人也有继承关系。例如学校人员包括学生、老师及职员老师又分为专任老师及兼任老师。学校的人事软件系统应定义类别关系如下

图2、 三代继承关系

程序不仅要定义类别也要定义其继承关系。



2. 定义继承关系

前面各章里已介绍如何定义类别本节将告诉您如何定义类
别之继承关系。兹举例说明之



程序的设计过程是
step 1. 定义基础类别(父类别)。如

Class Person

End Class

step 2. 定义衍生类别(子类别)。如

Class Teacher
Inherits Person

End Class
Class Student
Inherits Person

End Class

Inherits字眼之后为父类别名称。它表达了:Teacher 为Person之子类别且 Student为Person之子类别。现在已知道如何表达继承关系了然而子类别从父类别继承什么东西呢类别包含「资料」及「程序」。因之子类别继承父类别之资料及程序。现在请看看如何继承资料及程序。下述程序定义 Person 类别含有 2项资料及 3个程序

'ex01.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-----------------------------------------------------------------------------------------
Class Person
Private name As String
Private age As Integer
Public Sub SetValue(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
Public Function birthYear() As Integer
birthYear = 2001 - age
End Function
Public Sub Display()
Messagebox.Show("Name: " + name + " Age: " + str(age))
End Sub
End Class
'-----------------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
.......
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim mike As Person
mike = New Person()
mike.SetValue("Mike", 45)
mike.Display()
Messagebox.Show("BirthYear: " + Str(mike.birthYear()))
End Sub
End Class

此程序输出如下
Name: Mike Age: 45
BirthYear: 1956


所谓继承资料表示继承资料成员之定义而不是继承资料之值请详加区别之。类别定义资料成员(含型态及名称)对象诞生后对象内才有资料值。所以「类别继承」乃继承类别之定义不是继承对象之值。也就是说若父类别定义name及 age两个资料成员则子类别天生就拥有此两个资料成员所以子类别不需定义它们。所谓继承程序表示子类别天生就拥有父类别定义之程序成员。例如Person的子类别天生就具有 SetValue()、birthYear()及Display()程序。现在就来定义Person之子类别。

'ex02.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-----------------------------------------------------------------------------------------
Public Class Person
Private name As String
Private age As Integer
Public Sub SetValue(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
Public Function birthYear() As Integer
birthYear = 2001 - age
End Function
Public Sub Display()
Messagebox.Show("Name: " + name + " Age: " + str(age))
End Sub
End Class

Public Class Teacher
Inherits Person

End Class
'-----------------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
.......
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim steven As Teacher
steven = New Teacher()
steven.SetValue("Steven", 35)
steven.Display()
End Sub
End Class

此程序输出如下
Name: Steven Age: 35

表面上Teacher 类别中未定义数据项及程序但事实上已拥有name及 age两个资料成员也拥有 SetValue()、birthYear()及Display() 三个程序成员。因之steven为Teacher类别之对象它能呼叫SetValue()及Display()程序。在应用上子类别通常拥有自己的数据项及程序使其有别于父类别。例如

'ex03.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'------------------------------------------------------------------------------------------------------
Public Class Person
Private name As String
Private age As Integer
Public Sub SetValue(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
Public Function birthYear() As Integer
birthYear = 2001 - age
End Function
Public Sub Display()
Messagebox.Show("Name: " + name + " Age: " + str(age))
End Sub
End Class

Public Class Teacher
Inherits Person

Private salary As Decimal
Public Sub tr_SetValue( ByVal na As String, ByVal a As Integer, ByVal
sa As Decimal)
SetValue(na, a)
salary = sa
End Sub
Public Sub pr()
MyBase.Display()
Messagebox.Show("Salary: " + str(salary))
End Sub
End Class
'-----------------------------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
........
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim steven As Teacher
steven = New Teacher()
steven.tr_SetValue("Steven", 35, 35000)
steven.pr()
End Sub
End Class

此程序输出如下
Name: Steven Age: 35
Salary: 35000

现在Teacher 类别含有三个资料成员
1. name ──从Person类别继承而来。
2. age ──从Person类别继承而来。
3. salary ──自己定义的。

此外也含有五个程序成员
1. SetValue() ──从Person继承而来。
2. birthYear()──从Person继承而来。
3. Display() ──从Person继承而来。
4. tr_SetValue()──自己定义的。
5. pr()──自己定义的。

由于SetValue()为 Teacher之程序成员所以tr_SetValue()能直接呼叫SetValue()来设定name及age值之后tr_SetValue()自己设定salary之值。同理pr()能直接呼叫 Display()来显示name及age之内容之后pr()自己输出salary之值。也许您会问道子类别自己定义之程序是否能与父类别之程序同名称呢答案是肯定的而且是常见之写法。如果名称相同但是参数不一致(像参数个数不同或参数型态不同),就是父子类别之间的程序多重定义(Procedure Overloading)了,必须写上Overloads字眼。例如上述程序相当于──

'ex04.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'------------------------------------------------------------------------------------------
Class Person
Private name As String
Private age As Integer
Public Sub New()
End Sub
Public Sub SetValue(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
Public Function birthDay() As Integer
birthDay = 2001 - age
End Function
Public Sub Display()
Messagebox.Show("Name: " + name + " Age: " + str(age))
End Sub
End Class

Class Teacher
Inherits Person

Private salary As Decimal
Public Overloads Sub SetValue( ByVal na As String, ByVal a As Integer, ByVal
sa As Decimal)
SetValue(na, a)
salary = sa
End Sub
Public Sub pr()
MyBase.Display()
Messagebox.Show("Salary: " + str(salary))
End Sub
End Class
'------------------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
........
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim steven As Teacher
steven = New Teacher()
steven.SetValue("Steven", 35, 35000)
steven.pr()
End Sub
End Class

此程序输出如下
NAME: Steven
AGE : 35
Salary: 35000

此种情况Teacher 类别拥有两个 SetValue()程序一个由Person继承而来一个是自己定义的。同时也拥有两个Display()程序。此时计算机如何分辨它们呢计算机依据程序的参数来决定呼叫那一个程序,当您写成 steven.SetValue("Steven", 35, 35000)时,此SetValue()是子类别自己的SetValue()。而写成SetValue(na,a)时,则是由Person类别继承而来之SetValue()程序。此VB程序已定义如下之类别关系


接下来再为Person定义一个子类别── Student。程序如下

'ex05.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'------------------------------------------------------------------------------------------
Public Class Person
Private name As String
Private age As Integer
Public Sub New()
End Sub
Public Sub SetValue(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
Public Function birthDay() As Integer
birthDay = 2001 - age
End Function
Public Sub Display()
Messagebox.Show("Name: " + name + " Age: " + str(age))
End Sub
End Class

Public Class Teacher
Inherits Person

Private salary As Decimal
Public Overloads Sub SetValue( ByVal na As String, ByVal a As Integer, ByVal
sa As Decimal)
SetValue(na, a)
salary = sa
End Sub
Public Sub pr()
MyBase.Display()
Messagebox.Show("Salary: " + str(salary))
End Sub
End Class

Public Class Student
Inherits Person

Private student_number As Integer
Public Overloads Sub SetValue( ByVal na As String, ByVal a As Integer, ByVal
no As Integer)
SetValue(na, a)
student_number = no
End Sub
Public Sub pr()
MyBase.Display()
Messagebox.Show("StudNo: " + str(student_number))
End Sub
End Class
'-----------------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
........
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim x As New Person()
x.SetValue("Alvin", 32)
Dim y As New Student()
y.SetValue("Tom", 36, 11138)
x.Display()
y.pr()
End Sub
End Class

此程序输出
Name: Alvin Age: 32
Name: Tom Age: 36
StudNo: 11138

此时Student 类别含有name、age 及student_number三个资料成员。而且拥有 SetValue()、Person.SetValue() 、Display()、pr() 及birthYear()五个程序成员。于是建立了如下之继承关系


x 对象含name及age 两项资料指令──x.SetValue ("Alvin", 32)将资料存入x 对象中。因Student继承Person所以y 对象内含name、age 及student_number三项资料指令──y.SetValue("Tom", 36, 11138) 将资料存入y 对象中。上述 SetValue()程序之功能是设定对象之初值。可由建构者(Constructor) 代替之。所以此Student之定义相当于──

'ex06.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms

'----------------------------------------------------
Public Class Person
Private name As String
Private age As Integer
Public Sub New()
End Sub
Public Sub SetValue(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
Public Function birthDay() As Integer
birthDay = 2001 - age
End Function
Public Sub Display()
Messagebox.Show("Name: " + name + " Age: " + str(age))
End Sub
End Class

Public Class Teacher
Inherits Person

Private salary As Decimal
Public Overloads Sub SetValue(ByVal na As String, ByVal a As Integer, ByVal sa As Decimal)
SetValue(na, a)
salary = sa
End Sub
Public Sub pr()
MyBase.Display()
Messagebox.Show("Salary: " + str(salary))
End Sub
End Class

Public Class Student
Inherits Person

Private student_number As Integer
Public Sub New(ByVal na As String, ByVal a As Integer, ByVal no As Integer)
SetValue(na, a)
student_number = no
End Sub
Public Sub pr()
MyBase.Display()
Messagebox.Show("StudNo: " + str(student_number))
End Sub
End Class
'------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()

Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
........
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim x As New Person()
x.SetValue("Alvin", 32)
Dim y As New Student("Tom", 36, 11138)
x.Display()
y.pr()
End Sub
End Class

此程序输出
Name: Alvin Age: 32
Name: Tom Age: 36
StudNo: 11138

子类别之建构者呼叫父类别之SetValue()来设定对象初值。请仔细看y 对象之诞生过程y 诞生时建构者──

Public Sub New(ByVal na As String, ByVal a As Integer, ByVal no As Integer)
SetValue(na, a)
student_number = no
End Sub

它先呼叫父类别的自然建构者Person.New()一起诞生y 对象。此时Person.New()诞生如下

继承部分是Person.New()诞生的。Person.New()任务完成了轮到Student的建构者本身诞生(扩充)如下



诞生完毕开始执行Student建构者内之指令以设定y 之初值。首先呼叫父类别的SetValue() 于是SetValue()将值存入y 如下



最后执行指令── student_number = no设定student_number数据之初值



于是Student的建构者诞生y 对象也设定初值功成圆满。
上述的Student建构者呼叫父类别之自然建构者(因为Person类别未定义建构者计算机自动产生自然建构者)来协助诞生对象。如果Person类别定义了建构者Student建构者便能直接呼叫Person建构者了。例如

'ex07.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-----------------------------------------------------------------------------------------
Public Class Person
Private name As String
Private age As Integer
Public Sub New(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
Public Function birthDay() As Integer
birthDay = 2001 - age
End Function
Public Sub Display()
Messagebox.Show("Name: " + name + " Age: " + str(age))
End Sub
End Class

Public Class Teacher
Inherits Person

Private salary As Decimal
Public Sub New(ByVal na As String, ByVal a As Integer, ByVal sa As Decimal)
MyBase.New(na, a)
salary = sa
End Sub
Public Sub pr()
MyBase.Display()
Messagebox.Show("Salary: " + str(salary))
End Sub
End Class

Public Class Student
Inherits Person

Private student_number As Integer
Public Sub New(ByVal na As String, ByVal a As Integer, ByVal no As Integer)
MyBase.New(na, a)
student_number = no
End Sub
Public Sub pr()
MyBase.Display()
Messagebox.Show("StudNo: " + str(student_number))
End Sub
End Class
'-----------------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub

#Region " Windows Form Designer generated code "
........
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim x As New Person("Alvin", 32)
Dim y As New Student("Tom", 36, 11138)
x.Display()
y.pr()
End Sub
End Class

此程序输出
Name: Alvin Age: 32
Name: Tom Age: 36
StudNo: 11138

子类别之建构者──

Public Sub New(ByVal na As String, ByVal a As Integer, ByVal sa As Decimal)
......
End Sub

先呼叫父类别之建构者──

Public Sub New(ByVal na As String, ByVal a As Integer)
......
End Sub

协助诞生对象如下

接着执行父类别Person的建构者内之指令设定初值如下

Person建构者工作完成了轮到Student建构者的工作扩充对象如下



诞生完毕执行Student建构者内之指令设定初值


于是y 对象诞生完毕了。
子类别建构者呼叫父类别建构者之模式



例如Student建构者内的MyBase.New(na, a)指令将na及a值传递给Person建构者于是Person建构者设定name及age之初值。除了呼叫Person建构者之外还执行自己的指令──student_number = no 设定student_number之初值。Student类别之对象含有三个资料成员其中name及 age是由Person类别继承而来就藉Person建构者设定其初值。至于Student类别自己定义之资料成员student_number就由自己的指令──student_number = no设定其初值。
3. 藉「继承」扩充程序

程序之发展是渐进的软件内之类别需随企业之成长而不断扩充。类别扩充常源于
(1) 企业成长了产生了新类别。
例如某计算机公司过去制造大型及迷你计算机现在新推出个人计算机。就必须建立新子类别如下


图3、 程序扩充方法──衍生子类别

再如某银行过去提供支票帐户(Checking Account)及储蓄帐户(Saving Account)给客户现在拟增加定期帐户(CD Account)。就得新增子类别如下



这新类别CD_Account继承父类别Saving_Account及Account 的资料及程序。例如Account 之定义如下

'ex08.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'-----------------------------------------------------------------------------------
Class Account
Private Shared next_number As Integer
Protected acc_no As Integer
Protected name As String
Protected balance As Decimal

Shared Sub New()
next_number = 1000
End Sub
Public Sub New(ByVal na As String)
name = na
balance = 0
acc_no = next_number
next_number = next_number + 1
End Sub
Public Sub deposit(ByVal money As Decimal)
balance = balance + money
End Sub
Public Sub withdraw(ByVal money As Decimal)
balance = balance - money
End Sub
Public Sub close()
acc_no = -1
End Sub
End Class

Class Saving_Account
Inherits Account

Private interest_rate As Double
Public Sub New(ByVal na As String, ByVal rate As Double)
MyBase.New(na)
Me.interest_rate = rate
End Sub
Public Function comp_interest() As Double
comp_interest = balance * interest_rate
End Function
Public Sub display()
Messagebox.Show("ACC_NO: " + str(MyBase.acc_no))
Messagebox.Show("余额: " + str(Me.balance) + " 利息: "
+ str(comp_interest()))
End Sub
End Class
'-----------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
.......
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim saving_acc As New Saving_Account("Tom Bush", 0.085)
Dim account As Saving_Account
account = New Saving_Account("Linda Lin", 0.008)
account.deposit(5000)
account.withdraw(2500)
account.display()
account.close()
End Sub
End Class

此程序输出
ACC_NO: 1001
余额: 2500
利息: 20
因Saving_Account继承Account 所以Saving_Account类别亦拥有deposit() 、withdraw()及close() 三个程序。请换个角度从Saving_Account类别之设计者来看他透过继承关系来「借用」父类别之程序。「借用」又称为「再使用」(Resue) 能使得子类别简单但却强而有力。就如Saving_Account类别显得比Account 类别简单但它总共却含有deposit() 、withdraw()等6 个程序功能比Account 类别强大许多。对于指令──account.deposit(5000) 而言其有两种意义
I. Saving_Account继承Account 所以Saving_Account具有deposit() 程序可将5000存入account 对象。
II. Saving_Account为Account 之子类别它能借用(再使用)父类别之deposit() 程序来将5000存入account 对象。

这两者是一体的两面继承功能让软件师能不断新增子类别不断再使用现有类别之程序来简化子类别之复杂度。继承使得子类别拥有祖父类别之各种功能且再增加新功能再使用使得子类别尽量委托祖父类别来担任工作自己以逸待劳。因而善用继承功能时时心存再使用观念便能设计简单却功能强大的子类别了。而程序员的效率提升了软件之成本下降了此乃OOP 的理想目标之一。兹再扩充一个子类别CD_Account如下

'ex09.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'--------------------------------------------------------------------------------
Class Account
Private Shared next_number As Integer

Protected acc_no As Integer
Protected name As String
Protected balance As Decimal

Shared Sub New()
next_number = 1000
End Sub
Public Sub New(ByVal na As String)
name = na
balance = 0
acc_no = next_number
next_number = next_number + 1
End Sub
Public Sub deposit(ByVal money As Decimal)
balance = balance + money
End Sub
Public Sub withdraw(ByVal money As Decimal)
balance = balance - money
End Sub
Public Sub close()
acc_no = -1
End Sub
End Class

Class Saving_Account
Inherits Account

Private interest_rate As Double
Public Sub New(ByVal na As String, ByVal rate As Double)
MyBase.New(na)
Me.interest_rate = rate
End Sub
Public Function comp_interest() As Double
comp_interest = balance * interest_rate
End Function
Public Sub display()
Messagebox.Show("ACC_NO: " + str(MyBase.acc_no))
Messagebox.Show("余额: " + str(Me.balance) + " 利息: "
+ str(comp_interest()))
End Sub
End Class

Class CD_Account
Inherits Saving_Account

Public Sub New(ByVal na As String, ByVal rate As Double, ByRef b As Decimal)
MyBase.New( na, rate + 0.003 )
MyBase.deposit(b)
End Sub
End Class
'----------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
.......
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim a As CD_Account
a = New CD_Account("Linda Lin", 0.008, 2500)
a.display()
a.close()
End Sub
End Class

CD_Account除了在定义自己的New()之外,皆继承Saving_Account的成员。请您仔细阅读下述程序,看看跟上一个程序有何微妙差异?

'ex10.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'--------------------------------------------------------------------------------
Class Account
Private Shared next_number As Integer

Protected acc_no As Integer
Protected name As String
Protected balance As Decimal

Shared Sub New()
next_number = 1000
End Sub
Public Sub New(ByVal na As String)
name = na
balance = 0
acc_no = next_number
next_number = next_number + 1
End Sub
Public Sub deposit(ByVal money As Decimal)
balance = balance + money
End Sub
Public Sub withdraw(ByVal money As Decimal)
balance = balance - money
End Sub
Public Sub close()
acc_no = -1
End Sub
End Class

Class Saving_Account
Inherits Account

Private interest_rate As Double
Public Sub New(ByVal na As String, ByVal rate As Double)
MyBase.New(na)
Me.interest_rate = rate
End Sub
Public Function comp_interest() As Double
comp_interest = balance * interest_rate
End Function
Public Sub display()
Messagebox.Show("ACC_NO: " + str(MyBase.acc_no))
Messagebox.Show("余额: " + str(Me.balance) + " 利息: "
+ str(comp_interest()))
End Sub
End Class

Class CD_Account
Private acc As Saving_Account
Public Sub New(ByVal na As String, ByVal rate As Double, ByRef b As Decimal)
acc = New Saving_Account(na, rate + 0.003)
acc.deposit(b)
End Sub
Public Function comp_interest() As Double
comp_interest = acc.comp_interest()
End Function
Public Sub display()
acc.display()
End Sub
Public Sub Close()
acc.close()
End Sub
End Class
'----------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
.......
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim a As CD_Account
a = New CD_Account("Linda Lin", 0.008, 2500)
'a.deposit(5000) 'Error here!!
a.display()
a.close()
End Sub
End Class

(2) 环境改变了必须修正旧类别。
例如软件内含Sales 类别如下──

'ex11.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'----------------------------------------------------------------------------------
Class Sales
Protected sum As Double
Public Sub New()
sum = 0
End Sub
Public Overridable Sub input(ByVal amount As Double)
sum = sum + amount
End Sub
Public Sub display()
Messagebox.Show("The Sum Is: " + str(sum))
End Sub
End Class
'-----------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
........
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim x As New Sales()
x.input(3000.5)
x.input(7999.5)
x.input(15000)
x.display()
End Sub
End Class

此程序输出如下The Sum Is: 26000

input() 输入销售金额且将金额加总起来存于 sum变量中。display() 显示出总金额。随着企业之成长往往对软件之功能有新的需求。例如希望程序输出平均销售额。此时必须更新原来的软件其方法有二

(I) 改写 Sales类别之定义。
此为传统软件之维护方法就像一座房屋已不敷使用于是用推土机推掉重建之。通常这种方法并不佳原因是旧的软件有些功能仍然可用废弃重建实在可惜。若不想重建只想去修改它但是软件若很庞大得浪费人力去了解旧软件的结构弄通了之后才能加以修正显然不经济。进一步想于修正之过程中不经意而更动旧软件内仍可用之部分则原来正确之功能反而有遭破坏之虞
(II) 藉继承关系修正 Sales类别。
亦即定义 Sales之子类别来修正及扩充 Sales之功能。此时并未更动Sales 类别之定义所以不会破坏 Sales之功能。既然保存原有的良好功能又能增加新的功能岂非两全其美呢此「旧干发新枝」之景象即是千年神木得以茁壮且绿意盎然之道理也正是 OOP魅力的源头。现在就为 Sales定义个子类别叫 Sales_new如下

'ex12.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'------------------------------------------------------------------------------------
Class Sales
Protected sum As Double
Public Sub New()
sum = 0
End Sub
Public Overridable Sub input(ByVal amount As Double)
sum = sum + amount
End Sub
Public Sub display()
Messagebox.Show("The Sum Is: " + str(sum))
End Sub
End Class

Class Sales_new
Inherits Sales

Protected number As Integer
Public Sub New()
number = 0
End Sub
Public Overrides Sub input(ByVal amount As Double)
MyBase.input(amount)
number = number + 1
End Sub
Public Sub display_average()
Dim avg As Double
If number > 0 Then
avg = sum / number
MessageBox.Show("The Average Is : " + str(avg))
End If
End Sub
End Class
'------------------------------------------------------------------------------------
Public Class Form1
Inherits System.WinForms.Form

Public Sub New()
MyBase.New()
Form1 = Me
'This call is required by the Win Form Designer.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Windows Form Designer generated code "
.......
#End Region
Protected Sub Form1_Click( ByVal sender As Object, ByVal
e As System.EventArgs)
Dim x As New Sales_new()
x.input(3005.5)
x.input(5994.5)
x.input(15012.6)
x.display()
x.display_average()
End Sub
End Class


此程序输出
The Sum Is: 24012.6
The Average Is: 8004.2

子类别增加了新数据项number重新定义了input()使新input()保存父类别内之input()功能并加上number = number +1之运算。保留了父类别之display()但增加了display_average()程序。依此方法软件自然日益茁壮且历久弥新藉继承关系不断扩充乃为OOP之重要技术盼您善用之。n

JdrHTML5中文学习网 - HTML5先行者学习网
JdrHTML5中文学习网 - HTML5先行者学习网
(责任编辑:)
推荐书籍
推荐资讯
关于HTML5先行者 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助