html5中文学习网

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

VB.Net中文教程(3) 继承与封装性_.NET教程_编程技术

[ ] 已经帮助:人解决问题
封装|继承|教程|中文
1. 继承与封装性(Encapsulation)
1.1 公用与私有数据

前面已介绍「封藏性」(Encapsulation) 之观念。即是类别内所定义之资料成员只限于程序成员才能存取之。现在所面临之问题为子类别能否直接存取父类别之资料呢就如同儿女从父母亲继承了财产但能否取用或卖掉继承而来的财产呢如果可以显然违背了「封藏性」之理想。如果不行显然带给程序员莫大之限制。理论上百分之百的封藏性最为完美但应用上若给予子类别若干优待能提高程序之弹性及效率。为了解决此鱼与熊掌不可兼得之困境VB提供三种选择

(1) Public ──指定某些数据为公用的任何程序皆可直接取用之此时并无任何封藏作用。
(2) Protected ──指定某些资料为家族公用亦即只有子孙类别内之程序可取用非子孙类别之程序必须呼叫家族内之程序代为存取。
(3) Private ──指定某资料为类别私有只限于该类别之程序才可取用。子类别之程序也必须呼叫父类别之程序代为存取此时具百分之百封藏性。

先前介绍「封装性」基本概念时,您已经认识了Public和Private的用意了,至于Protected则配合继承来使用,于是在此特别强调它。
由于VB向现实妥协开了方便之门无百分之百封藏性所以有些人认为 VB并非完美的 OOP语言。您认为如何呢请看个程序

'ex01.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'---------------------------------------------------------
Class Person
Private name As String
Public age As Integer
Public Sub New(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
End Class

Class Teacher
Inherits Person

Public salary As Single
Public Sub New(ByVal na As String, ByVal a As Integer, ByVal sa As Single)
MyBase.New(na, a)
salary = sa
End Sub
Public Sub modifyAge(ByVal a As Integer)
age = a
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 crag As New Teacher("Crag", 38, 45000)
crag.modifyAge(42)
MessageBox.Show( "AGE: " + str(crag.age) + ", SALARY: "
+ str(crag.salary))
End Sub
End Class

此程序输出如下
AGE: 42 SALARY: 45000

Person之age资料成员定义为 Public表示 age为公用数据任何程序皆可存取之。因之Teacher 之 modifyAge()可使用age这名称。相对地于 Teacher类别中就不得使用name这名称因为name定义为Privatec表示name为Person类别之私有资料。再看Teacher类别之salary资料它定义为Public表示公用之意。所以Form1_Click()可直接使用 crag.salary格式取得salary之值。然而不能写成crag.name 因为name为私有资料。例如,下述程序是不对的:

'ex02.bas
'Some Error Here!
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'---------------------------------------------------------
Class Person
Private name As String
Public age As Integer
Public Sub New(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
End Class

Class Teacher
Inherits Person

Public salary As Single
Public Sub New(ByVal na As String, ByVal a As Integer, ByVal sa As Single)
MyBase.New(na, a)
salary = sa
End Sub
Public Sub modifyName(ByVal na As String)
name = na 'Error Here!
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 crag As New Teacher("Crag", 38, 45000)
crag.modifyName("Crag Clinton")
MessageBox.Show( "AGE: " + str(crag.age) + ", SALARY: "
+ str(crag.salary))
End Sub
End Class

因为name是Person类别的私有资料,在子类别Teacher的modifyName()里不能使用此资料名称,所以错了。如果将Person类别定义为

'ex03.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'---------------------------------------------------------
Class Person
Protected name As String
Public age As Integer

Public Sub New(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
Public Function GetName() As String
GetName = name
End Function
End Class

Class Teacher
Inherits Person

Public salary As Single
Public Sub New(ByVal na As String, ByVal a As Integer, ByVal sa As Single)
MyBase.New(na, a)
salary = sa
End Sub
Public Sub modifyName(ByVal na As String)
name = na
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 crag As New Teacher("Crag", 38, 45000)
crag.modifyName("Crag Clinton")
MessageBox.Show( "AGE: " + str(crag.age) + ", NAME: "
+ crag.GetName())
End Sub
End Class

此程序输出:
AGE: 42, NAME: Crag Clinton

此时name为家族公用之资料凡是Person之子孙类别皆可取用之。但家族外之程序(如 Form1_Click()程序)仍不得直接使用之。如果上述定义改为

Class Person
Protected name As String
Private salary As Decimal
Public age As Integer

Public Sub New(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
End Class

此时salary为类别私有其它类别不得使用。name为家族私有家族外之类别不得使用。age为公用任何类别皆可用。


1.2 公用与私有程序
上节介绍过资料成员有 Private、Protected 及Public之分。同样地程序成员也可分为 Private、Protected 及Public。虽然在应用上程序成员大多定义为Public但必要时也能将过程定义为Private 或 Protected。私有程序和私有资料一样只限于该类别之程序才能呼叫它。例如

'ex04.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'----------------------------------------------------------------------
Class Person
Private name As String
Private age As Integer
Private Sub modifyAge(ByVal a As Integer)
age = a
End Sub
Public Sub New(ByVal na As String, ByVal a As Integer)
name = na
age = a
End Sub
Public Sub modify(ByVal na As String, ByVal a As Integer)
name = na
modifyAge(a)
End Sub
Public Sub Show()
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 p1 As New Person("David", 25)
p1.Show()
p1.modify("David Smith", 28)
p1.Show()
End Sub
End Class


此程序输出:
Name: David Age: 25
Name: David Smith Age: 45

modifyAge()为私有程序New()及modify()为公用程序。modifyAge()为Person类别之程序成员所以modify()能呼叫modifyAge()。Person类别外之函数不能呼叫modifyAge()。例如在Form1_Click()中可写着 p1.modify()因为modify()为公用程序。但于Form1_Click()内就不可写着 p1.modifyAge()因为modifyAge()为 Private函数。如果放宽对modifyAge()之限制使Person之子类别能呼叫modifyAge()就须定义modifyAge()为 Protected函数如下

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

Class Teacher
Inherits Person

Public Sub New(ByVal na As String, ByVal a As Integer)
MyBase.New(na, a)
End Sub
Public Sub modify(ByVal na As String, ByVal a As Integer)
MyBase.name = na
MyBase.modifyAge(a)
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 p1 As New Teacher("David", 25)
p1.Show()
p1.modify("Kent Smith", 45)
p1.Show()
End Sub
End Class


此程序输出:
Name: David Age: 25
Name: Kent Smith Age: 45

此时子孙类别之函数能呼叫modifyAge()但家族外之类别仍不可呼叫它。总结归纳为简单规则
◎如果允许任何类别使用就宣告为Public。
◎如果允许子类别使用就宣告为Protected 。
◎如果允许本类别使用就宣告为Private 。
请在看个例子:

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

Class Teacher
Inherits Person

Public Sub New(ByVal na As String, ByVal a As Integer)
MyBase.New(na, a)
End Sub
Protected Sub modify(ByVal na As String, ByVal a As Integer)
MyBase.name = na
MyBase.modifyAge(a)
End Sub
End Class

Class FullTime_Teacher
Inherits Teacher

Public Sub New(ByVal na As String, ByVal a As Integer)
MyBase.New(na, a)
End Sub
Public Sub modifyValue(ByVal na As String, ByVal a As Integer)
MyBase.modify(na, a)
End Sub
Public Sub modifyData(ByVal na As String, ByVal a As Integer)
MyBase.name = na
MyBase.modifyAge(a)
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 p1 As New FullTime_Teacher("David", 25)
p1.Show()
p1.modifyValue("Kent Smith", 45)
p1.Show()
End Sub
End Class

此程序输出:
Name: David Age: 25
Name: Kent Smith Age: 45


Show()是Person类别的Public程序,孙子类别FullTime_Teacher继承之,成为FullTime_Teacher类别的Public程序,所以Form1_Click()程序能写着指令:p1.Show()。name和modifyAge()是Person的Protected成员,Teacher的modify()程序里能直接使用它们。而且FullTime_Teacher的modifyData()程序里能直接使用它们。但是Form1_Click()就无法使用它们。modify()是Teacher的Protected成员,FullTime_Teacher的modifyValue()程序里能直接使用它们,但Form1_Click()就不行使用。所以若将上述Form1_Click()的指令改为如下,就不对了:

Protected Sub Form1_Click( ..... )
Dim p1 As New FullTime_Teacher("David", 25)
p1.Show()
p1.modify("Kent Smith", 45) 'Error!
p1.modifyAge(24) 'Error!
p1.Show()
End SubEnd Class
n



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