VB.Net中文教程(3) 繼承與封裝性 (轉)
請注意 ......
著作權所有人:物澤事業股份有限公司、
MISOO技術顧問團隊、物件導向雜誌作者、等。
u本摘自 物件導向雜誌、精通物件觀念與技術等書籍著作。
u本檔案僅供您的參閱,請遵守著作權法,不得做其它商業用途。
主題: 繼承與封裝性
?????????? 內容 ??????????
v 1. 繼承與封藏性
1. 繼承與封裝性(Encapsulation)
1.1 公用與私有資料
前面已介紹「封藏性」(Encapsulation) 之觀念。即是﹕類別內所定義之資料成員﹐只限於成員才能存取之。現在所面臨之問題為﹕子類別能否直接存取父類別之資料呢﹖就如同﹕兒女從父母親繼承了財產﹐但能否取用或賣掉繼承而來的財產呢﹖如果可以﹐顯然違背了「封藏性」之理想。如果不行﹐顯然帶給程式設計師莫大之限制。理論上﹐百分之百的封藏性最為完美﹔但應用上﹐若給予子類別若干優待﹐能提高程式之彈性及。為了解決此魚與熊掌不可兼得之困境﹐VB提供三種選擇﹕
(1) Public ──指定某些資料為公用的﹐任何程式皆可直接取用之﹔此時並無任何封藏作用。
(2) Protected ──指定某些資料為家族公用﹐亦即只有子孫類別內之程式可取用﹐非子孫類別之程式必須呼叫家族內之程式代為存取。
(3) Private ──指定某資料為類別私有﹐只限於該類別之程式才可取用。子類別之程式也必須呼叫父類別之程式代為存取﹐此時具百分之百封藏性。
先前介紹「封裝性」基本概念時,您已經認識了Public和Private的用意了,至於Protected則配合繼承來使用,於是在此特別強調它。
由於VB向現實妥協﹐開了方便之門﹐無百分之百封藏性﹔所以有些人認為 VB並非完美的 語言。您認為如何呢﹖請看個程式﹕
'ex01.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.s
'---------------------------------------------------------
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 FoDesigner.
InitializeComponent()
'TODO: Add any initialization after the InitializeComponent() call
End Sub
'Form overrs dispose to clean up the component list.
Public Overrides Sub Dispose()
MyBase.Dispose()
components.Dispose()
End Sub
#Region " Form Designer generated code "
.......
#End Region
Protected Sub Form1_Click( ByVal sender As ,
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/10748419/viewspace-1004281/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- VB.Net中文教程(1) 類別與封裝性 (轉)封裝
- VB.Net中文教程(4) 類別繼承(Inheritance)關係 (轉)繼承
- 封裝和繼承封裝繼承
- Java入門教程九(封裝繼承多型)Java封裝繼承多型
- 封裝、繼承和多型封裝繼承多型
- Swift中文教程(十三) 繼承Swift繼承
- python極簡教程07:封裝、多型和繼承Python封裝多型繼承
- 精通ASP.NET(基於VB.NET)(四)VB.NET繼承 (轉)ASP.NET繼承
- 繼承與介面 (轉)繼承
- 面向2-封裝、繼承、多型封裝繼承多型
- java 的 四 個 基 本 特 性 ——封裝 繼承 多型 抽象Java封裝繼承多型抽象
- go物件導向思想:封裝、繼承、多肽Go物件封裝繼承
- aardio 實現封裝繼承多型封裝繼承多型
- 多繼承 與 多重繼承繼承
- Henry的VB.NET之旅(九)—介面繼承繼承
- go語言中的封裝,繼承和多型Go封裝繼承多型
- java封裝繼承以及多型(含程式碼)Java封裝繼承多型
- Java的三大特性:封裝、繼承、多型Java封裝繼承多型
- Java學習day09—-封裝和繼承Java封裝繼承
- 【django-vue】封裝logger 封裝全域性異常 封裝response 資料庫配置 使用者表繼承AbstractUser配置DjangoVue封裝資料庫繼承
- VB.Net中文教程(11) Prototype樣式 (轉)
- Henry的VB.NET之旅(十一)—可視繼承繼承
- 物件導向三大特性-----封裝、繼承、多型物件封裝繼承多型
- 物件導向三大特徵(封裝/繼承/多型)物件特徵封裝繼承多型
- c# 中的封裝、繼承、多型詳解C#封裝繼承多型
- JAVA物件導向基礎--封裝 繼承 多型Java物件封裝繼承多型
- css可繼承屬性和非繼承屬性一覽CSS繼承
- VB.Net中文教程(2) Composite樣式 (轉)
- VB.Net中文教程(7) Me參考值 (轉)
- VB.Net中文教程(5)程式多重定義 (轉)
- VB.Net中文教程(6) 母子物件關係 (轉)物件
- 好程式設計師前端教程css中可被繼承和不可被繼承的屬性程式設計師前端CSS繼承
- c++學習(1)--C++封裝、繼承、多型C++封裝繼承多型
- 重讀C++之一:封裝、繼承和多型C++封裝繼承多型
- 繼承與派生繼承
- css屬性的可繼承性CSS繼承
- odoo 繼承(owl繼承、web繼承、view繼承)Odoo繼承WebView
- VB.Net中文教程(13) Whole-Part關係 (轉)