VB.Net中文教程(3) 继承与封装性 (转)

VB.Net中文教程(3) 继承与封装性 (转)[@more@]

请注意 ......
著作权所有人:物泽计算机事业股份有限公司、
  MISOO对象技术顾问团队、对象导向杂志作者、等。
u本文件摘自 对象导向杂志、精通对象观念与技术等书籍著作。
u本文件仅供您的参阅,请遵守著作权法,不得做其它商业用途。


  主题:  继承与封装性


??????????  内容  ??????????
v 1. 继承与封藏性

 


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

 


 


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10790663/viewspace-954132/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10790663/viewspace-954132/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值