兩個項目A和B,A已經(jīng)編譯通過了,重新生成解決方案,右鍵B項目添加引用,找到A項目的dll,引用進(jìn)來就可以了。
成都創(chuàng)新互聯(lián)公司專注于企業(yè)全網(wǎng)營銷推廣、網(wǎng)站重做改版、鳳岡網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5、商城開發(fā)、集團公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為鳳岡等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
繼承概述
面向?qū)ο缶幊?(OOP) 語言的一個主要功能就是 繼承 繼承是指這樣一種能力 它可以使用現(xiàn)有類的所有功能 并在無需重新編寫原來的類的情況下對這些功能進(jìn)行擴展 在 Microsoft? Visual Basic? NET 發(fā)布之前 Visual Basic 程序員并不具備這種能力 在 Visual Basic NET 中 您可以繼承 Microsoft NET 框架中的類 也可以繼承您自己創(chuàng)建的類 在本文中 我們將學(xué)習(xí)如何使用繼承 并了解繼承是如何大大縮短編程時間的 簡單示例
在您創(chuàng)建的許多類中 您會發(fā)現(xiàn)您常常需要與先前創(chuàng)建的類中的屬性和方法相同的屬性和方法 例如 如果有一個名為 Person 類的基類 該類包含 LastName 和 FirstName 屬性以及 Print 方法 您會發(fā)現(xiàn)對于 Employee 類您也需要這些屬性和方法 您可能還需要其他屬性 例如 EmployeeID 和 Salary 如果從 Person 類(基類)繼承 您可以將這些屬性添加到新的 Employee 類中 并且仍然可以訪問 Person 類中的所有屬性 繼承是指某個類可將其自身定義為具有某個特定類的所有屬性和方法 然后再通過添加其他屬性和方法對基類的定義進(jìn)行擴展的能力
繼承術(shù)語
在深入研究這個主題之前 讓我們先來定義幾個術(shù)語 通過繼承創(chuàng)建的新類稱為 子類 被繼承的類稱為 基類 父類 或 超類 在某些 OOP 語言中 一個子類可以繼承多個基類 也就是說 如果有一個 Person 類和一個 Car 類 則 Driver 類可以繼承這兩個類的所有屬性和方法 而在 NET 中 只允許單一繼承 因此每個子類只能有一個基類
NET 支持三類繼承 實現(xiàn)繼承 接口繼承和可視繼承 實現(xiàn)繼承是指使用基類的屬性和方法而無需額外編碼的能力 接口繼承是指僅使用屬性和方法的名稱 但是子類必須提供實現(xiàn)的能力 可視繼承是指子窗體(類)使用基窗體(類)的外觀和實現(xiàn)代碼的能力 在 NET 中 一個類可以從某個基類繼承而來 而這個基類又可以從另外一個類繼承而來 而且 您可以在一個類中使用一個或多個接口
使用繼承的原因
繼承可以避免重復(fù)編寫相同的代碼 因此十分有用 如果有兩個單獨的類 而每個類都必須實現(xiàn) FirstName 和 LastName 屬性 則可能會出現(xiàn)重復(fù)代碼 如果要更改某個屬性的實現(xiàn)方式 則需要查找已實現(xiàn)這些屬性的所有類以進(jìn)行更改 這不僅要耗費大量時間 還增加了不同類中出現(xiàn)錯誤的風(fēng)險
在考慮使用繼承時 有一點需要注意 那就是兩個類之間的關(guān)系應(yīng)該是 屬于 關(guān)系 例如 Employee 是一個人 Manager 也是一個人 因此這兩個類都可以繼承 Person 類 但是 Leg 類卻不能繼承 Person 類 因為腿并不是一個人
覆蓋
從基類中繼承功能時 您可能會發(fā)現(xiàn)在基類中編寫的一般方法僅執(zhí)行繼承類所需的部分功能 要執(zhí)行所需的全部功能 您可以在新類中覆蓋基類的方法 而無需使用新的名稱創(chuàng)建一個全新的方法
進(jìn)行覆蓋時 您可以選擇完全覆蓋基類的方法 也可以在繼承類中編寫代碼來執(zhí)行某些操作 然后再調(diào)用基類的方法 在覆蓋時 請務(wù)必仍然使用與原始方法相同的合約(參數(shù)和返回類型) 也可以選擇先調(diào)用基類的方法 然后在執(zhí)行完基類的方法后編寫其他代碼
繼承基類
繼承使您可以在一個類中使用另一個類的全部屬性和方法 您可以使用關(guān)鍵字 Inherits 來獲得基類的功能 而無需將代碼從一個類復(fù)制并粘貼到另一個類中
實現(xiàn)繼承
本文將創(chuàng)建一個新類 LineDelim 它將繼承 Creating Classes in NET(英文)一文中創(chuàng)建的 Line 類的所有功能 之后 本文將通過添加兩個其他屬性和一個方法對 Line 類進(jìn)行擴展 要添加的第一個屬性是 Delimiter 使用它可以獲得一個分隔符字符 并將其設(shè)置到類中 此分隔符將用于將行中的所有空格替換為分隔符字符 要添加的第二個屬性是 OriginalLine 它將用于在向文本行插入新的分隔符之前保留文本的原始行 要創(chuàng)建的新方法是 ReplaceAll() 它將用于將文本行中的所有空格替換為分隔符字符 然后我們將學(xué)習(xí)如何覆蓋 GetWord 方法 以便使用此分隔符(而不是空格)分隔文本行并搜索第一個詞 構(gòu)建示例窗體
要創(chuàng)建窗體 請單擊 Project(項目) 然后單擊 Add Windows Form(添加 Windows 窗體) 將窗體命名為 frmLineTest VB 并單擊 OK(確定)
然后在該窗體上創(chuàng)建相應(yīng)的控件并設(shè)置屬性
構(gòu)建 Line 類
接下來將構(gòu)建要繼承的 Line 類
從菜單中單擊 Project(項目) 然后單擊 Add Class(添加類) 鍵入如下所示的代碼
Public Class LinePrivate mstrLine As StringProperty Line() As StringGetReturn mstrLineEnd GetSet(ByVal Value As String)mstrLine = ValueEnd SetEnd PropertyReadOnly Property Length() As IntegerGetReturn mstrLine LengthEnd GetEnd PropertyPublic Function GetWord() As StringDim astrWords() As StringastrWords = mstrLine Split( ToCharArray())Return astrWords( )End FunctionEnd Class
創(chuàng)建子類 既然窗體和基類都已經(jīng)創(chuàng)建完畢 現(xiàn)在便可以開始執(zhí)行繼承了
單擊 Project(項目) 然后單擊 Add Class(添加類) 將該類命名為 LineDelim vb 并單擊 OK(確定) 添加新類時 請修改 Visual 所創(chuàng)建的代碼 使之與下面的示例代碼相似
Public Class LineDelimInherits Line
End Class
因為添加了 Inherits Line 語句 所以您可以在這一新創(chuàng)建的類中使用 Line 類的所有屬性和方法
試一試打開 frmLineTest vb 窗體 雙擊 Get Word(取詞)按鈕 向此按鈕的單擊事件過程添加以下代碼
Protected Sub btnFirst_Click(ByVal sender As Object _
ByVal e As System EventArgs) Handles btnFirst ClickDim oLine As LineDelim = New LineDelim()oLine Line = txtLine TexttxtFirstWord Text = oLine GetWord()End Sub
運行項目 并在窗體上單擊 Get Word(取詞)按鈕 您將看到 The 一字出現(xiàn)在按鈕旁邊的只讀文本框中 Inherits 語句的功能非常強大 只需要使用這一個語句 就可以在 LineDelim 類中使用 Line 類的所有屬性和方法 盡管這個新類尚未執(zhí)行任何新的操作 但它卻表明從 Line 類中繼承的所有代碼都可以正常工作
添加其他功能 現(xiàn)在 您可以使用其他屬性和方法對 LineDelim 類進(jìn)行擴展 要向 LineDelim 類添加兩個新的屬性 請執(zhí)行以下步驟
在上一部分添加的 Inherits 語句后添加兩個 Private 變量 如下所示
Private mstrDelim As String = Private mstrOriginal As String
鍵入如下代碼 為這兩個 Private 變量添加適當(dāng)?shù)?Property 語句 您可以將以下代碼放在上面輸入的兩行代碼后面(緊挨這兩行)
Public Property Delimiter() As StringGetReturn mstrDelimEnd GetSet(ByVal Value As String)mstrDelim = ValueEnd SetEnd PropertyPublic ReadOnly Property OriginalLine() As StringGetReturn mstrOriginalEnd GetEnd Property
現(xiàn)在您可以使用 Delimiter 屬性設(shè)置并獲取 Private 變量 mstrDelim 的值
如果不希望其他人更改這些屬性 您可以將屬性設(shè)為只讀 要執(zhí)行此操作 請不再使用 Set 語句 并在 Property 語句中添加 ReadOnly 屬性 有關(guān)示例 請參見上面代碼中顯示的 OriginalLine 屬性聲明
接下來 需要創(chuàng)建一個稱為 ReplaceAll 的方法 此方法可以將文本行中的所有空格替換為傳遞到 Delimiter 屬性中的分隔符字符
Public Function ReplaceAll() As StringmstrOriginal = MyBase LineReturn MyBase Line Replace( mstrDelim ToChar())End Function
ReplaceAll 方法通過基類的 Line 方法檢索原始文本行 而以前從基類中檢索屬性時使用的是 MyBase Line 語法 ReplaceAll 函數(shù)將 MyBase Line 屬性的值放入您剛剛為該類創(chuàng)建的 Private 變量 mstrOriginal 中 String 數(shù)據(jù)類型的 Replace 方法將字符串字符的所有實例替換為在 Delimiter 屬性中設(shè)置的新分隔符字符 mstrDelim MyBase 關(guān)鍵字 可以從任一子類使用 MyBase 關(guān)鍵字 以調(diào)用基類中的任何屬性或方法 即使基類的方法在子類中已被覆蓋 您也可以使用該關(guān)鍵字對其進(jìn)行調(diào)用 例如 如果在基類中存在 ReplaceAll 方法 但在子類中該方法已被覆蓋 您可以從子類的 ReplaceAll 方法中調(diào)用基類的 ReplaceAll 方法
試一試打開 frmLineTest VB 窗體 雙擊 Replace(替換)以調(diào)出單擊事件過程 在 btnReplace 按鈕的單擊事件中編寫以下代碼
Protected Sub btnReplace_Click( _ ByVal sender As Object _ByVal e As System EventArgs) Handles btnReplace ClickDim oLine As LineDelim = New LineDelim()oLine Delimiter = txtDelim TextoLine Line = txtLine TexttxtReplace Text = oLine ReplaceAll()End Sub
此代碼將 Delimiter 屬性設(shè)置為在示例窗體的 txtDelimiter 文本框中輸入的值 然后您可以調(diào)用 ReplaceAll 方法 將文本行中的所有空格更改為新的分隔符字符
按 F 鍵運行該項目 單擊 Replace(替換) 您將看到 在此按鈕旁邊的文本框中 句中的每個詞之間都有一個逗號 覆蓋方法 添加 Delimiter 屬性后 您可能想更改 LineDelim 類中的 GetWord 方法 以便使用相應(yīng)的分隔符替代 Line 類使用的單個空格 因為您不一定想更改基類 所以需要覆蓋 LineDelim 類中 GetWord 方法的功能 在 LineDelim 類中創(chuàng)建新的 GetWord 方法之前 您需要在 Line 類的 GetWord 方法聲明中添加一個關(guān)鍵字
在 Solution Explorer(解決方案資源管理器)窗口中 打開 Line vb 類的代碼窗口 找到 GetWord 方法的聲明(聲明不包含參數(shù)) 如下所示 Public Overloads Function GetWord() As String在函數(shù)聲明中添加關(guān)鍵字 Overridable 如下所示(沒有此關(guān)鍵字 就無法覆蓋此方法) Public Overridable Overloads Function GetWord() As String打開 LineDelim vb 類 并使用如下代碼添加新的 GetWord 方法
Public Overloads Overrides Function GetWord() As StringDim astrWords() As StringastrWords = MyBase Line Split(mstrDelim ToCharArray())Return astrWords( )End Function
如果要更改基類中方法的功能 則有必要在函數(shù)聲明中添加 Overrides 關(guān)鍵字 現(xiàn)在 LineDelim 類中的 GetWord 方法就可以使用 Delimiter 屬性的值來分隔句中的詞
如果只覆蓋其中一個 GetWord 方法 則代碼只能查看這一個版本的方法 而無法調(diào)用其他版本的 GetWord 方法 要顯示所有方法 您必須覆蓋每一個方法 就象您在 LineDelim 類中所執(zhí)行的操作一樣
試一試按 F 鍵運行該項目 在句中的每個詞之間都輸入一個逗號 并在 Delimiter(分隔符)文本框中輸入一個逗號 單擊 Get Word(取詞) 句中的第一個詞將出現(xiàn)在該按鈕旁邊的文本框中
抽象類 在本文上一部分的示例中 我們學(xué)習(xí)了如何創(chuàng)建 Person 對象 這是因為我們想處理普通的人 但是您可能會發(fā)現(xiàn) 如果不先添加一些特定的行為和/或數(shù)據(jù) 就無法使用 Person 類執(zhí)行任何操作 因此您可以將 Person 類變?yōu)槌橄箢?抽象類僅定義將由子類創(chuàng)建的一般屬性和方法
將 Person 類定義為只能被繼承的抽象類 而不是在運行時實際創(chuàng)建的對象 從該類繼承的每個類(如 Employee 類)都將使用特定的功能來創(chuàng)建所有相應(yīng)的屬性和方法 例如 Employee 類將創(chuàng)建實際的 Print 方法 而 Person 類僅定義必須存在 Print 方法 Person 類中沒有與 Print 方法相關(guān)聯(lián)的代碼 使用抽象類的原因有多種 對于強制子類設(shè)計人員實現(xiàn)應(yīng)用程序通常所需的所有接口 抽象類非常有用 您可以在不破壞客戶端應(yīng)用程序的情況下向子類添加新方法 這是使用接口所無法實現(xiàn)的 可以在基類中提供許多默認(rèn)實現(xiàn)方法 從而減少子類需要完成的工作量
接口繼承 創(chuàng)建抽象類時 請使用關(guān)鍵字 Interface 而不是 Class 為接口命名 然后定義需要子類實現(xiàn)的所有屬性和方法 這是因為基類中沒有可以實現(xiàn)的屬性和方法 它只包含一般數(shù)據(jù) 而不包含方法 您所創(chuàng)建的只是一個合約 它規(guī)定所有使用此接口的子類都必須遵循一定的規(guī)則
現(xiàn)在 請在已創(chuàng)建的項目中添加一個新類 從 Visual Studio 菜單中 單擊 Project(項目) 然后單擊 Add Class(添加類) 在類中添加以下代碼
Interface PersonProperty FirstName() As StringProperty LastName() As String
Sub Print()Sub Talk()End Interface
您會發(fā)現(xiàn) 您定義屬性和子過程的方法與您通常定義這些屬性和過程的方法一樣 唯一的差別在于 您沒有為它們編寫任何代碼 現(xiàn)在來看看如何在類定義中使用此接口
在上一步驟創(chuàng)建的類文件中添加以下代碼
Public Class EmployeeImplements PersonPrivate mstrFirstName As StringPrivate mstrLastName As StringProperty FirstName() As String _Implements Person FirstNameGetReturn mstrFirstNameEnd GetSetmstrFirstName = ValueEnd SetEnd PropertyProperty LastName() As String _Implements Person LastNameGetReturn mstrLastNameEnd GetSetmstrLastName = ValueEnd SetEnd PropertySub Print() Implements Person Print 在此處添加一些代碼 End Sub
Sub Talk() Implements Person Talk 在此處添加一些代碼End SubEnd Class
在 Employee 類定義之后的第一行是 Implements Person 此關(guān)鍵字表示您要遵守 Person 接口中定義的合約 現(xiàn)在您可以定義該合約中的所有屬性和方法 在每一個 Property 語句后面 都必須包含 Implements 關(guān)鍵字 并且必須指定接口的名稱和您正在使用的方法/屬性的名稱(兩個名稱之間有一個點 [ ]) Visual 將跟蹤每一個接口 在所有接口創(chuàng)建完畢之前 您不能編譯應(yīng)用程序 如果要運行代碼 則需要創(chuàng)建相應(yīng)的子過程 因為在上面的示例中這些子過程被保留為空 創(chuàng)建所有子過程后 您就可以與您通常創(chuàng)建并使用任何其他對象一樣 聲明并使用新的 Employee 對象了
選擇要使用的繼承類型 有時候很難決定到底是使用實現(xiàn)繼承還是使用接口繼承 很多情況下 可能兩種繼承都會用到 但都只涉及一小部分 例如 您可能需要在 Line 類中添加必須被子類覆蓋的方法定義 在過程定義中使用 MustOverride 關(guān)鍵字即可實現(xiàn)此操作
Public MustOverride Sub Init()將此定義添加到類中以后 其作用類似于一個接口 在子類中 必須定義 Init 方法 并且該方法必須使用 Overrides 關(guān)鍵字 以下是如何定義 Init 方法的示例
Public Overrides Sub Init()mstrDelim = mstrLine = 測試行 End Sub同樣 請記住使用 Overrides 關(guān)鍵字 該關(guān)鍵字用于通知編譯器此方法將覆蓋父類中的 Init 方法
注意 Microsoft NET 框架的聯(lián)機幫助中提供了設(shè)計指南 可以幫助您決定要使用的繼承類型 阻止繼承在某些情況下 您可能不希望其他類繼承您的類 如果是這樣 您可以使用關(guān)鍵字 NotInheritable 來阻止類的繼承
Public Class NotInheritable Employee 類定義End ClassVisual Basic 以來的新增功能
使用 Visual Basic NET 您可以繼承 NET 框架包含的所有類 您可以創(chuàng)建自己的類 使這些類繼承現(xiàn)有的類 并通過對代碼進(jìn)行簡單更改來添加或刪除功能
lishixinzhi/Article/program/net/201311/11397
VB.net
Public?Class?父類
End?Class
Public?Class?子類
Inherits?父類
End?Class