向美術教師交做業時,一位學生只交了一張白紙。
老師問:」畫呢?」
學生答:」這兒?」他指着白紙說。
老師:」你畫的是什麼?」
學生:」牛吃草。」
老師:」草呢?」
學生:」牛吃光了。」
老師:」牛呢?」
學生:」草吃光了,牛還站在那裏幹什麼?」
ide
1、抽象基類函數
正若有個好爹能夠少奮鬥二十同樣,父類自己是很是有用的,能夠進行實例化,也能夠不能實例化,作個樣子,好處很大。spa
一、MustInheit.net
基類可實例化,但也能夠不實例化(或者禁止建立該類的對象),這時,只能建立子類,以及子類的對象。設計
能夠用MustInherit來指明該基類不能建立對象。code
注意:這不表示不能聲明基類(以下例Person)類型的變量,只是不能用New Peron來建立對象。orm
同時在這個時候,咱們還可繼續使用共享辦法(由於它只屬於類,不屬於對象)對象
二、MustOverideblog
指明只能由子類重寫的方法(sub,funciton,property),此類方法只有方法頭,而無具體的實現代碼。所以不能建立對象。繼承
故: 類中含有MustOveride時,此類必須由MustInherit進行聲明。即:
只能在屬性和過程聲明語句中使用 MustOverride。 指定 MustOverride 的屬性或過程必須是類的成員,而且該類必須標
記爲 MustInherit。
Public MustInherit Class Person '只能被繼承 Private mName As String Private mBirthDate As Date Private mID As String Public Event NameChanged(ByVal newName As String) Public Event DataChanged(ByVal field As String, ByVal newValue As Object) Public MustOverride Function LifeExpectancy() As Integer '無實現代碼,只能被子類重寫 '...... End Class
上面聲明Mustoveride的函數LifeExpectancy只有方法頭,無實現代碼,此類方法也稱「抽象方法」或「純虛擬函數」
任何繼承此類的子類,必須重寫這些抽象方法,不然將產生語法錯誤,子類也不會編譯。
故在子類中添加:
'=======子類Employee中重寫基類的純虛函數=============== Public Overrides Function LifeExpectancy() As Integer Return 90 End Function
三、抽象基類
MustInherit及MustOverride同時出現該類時,此類被稱爲抽象基類。或者說:含有抽象方法的類叫抽象基類。
抽象基類頗有用,能夠前期只架上抽象基類這個架子,每一個子類根據本身狀況進行重寫適合本身的方法。
注意的是,此時子類都必須有抽象方法的實現代碼,不然出錯。
Public MustInherit Class AbstractBaseClass Public MustOverride Sub DoSomething() Public MustOverride Sub DoOtherSomething() End Class '接口 Public Interface IAbstractBaseClass Sub DoSomething() Sub DoOtherSomething() End Interface
某些方面,抽象基類與Interface接口概念類似,上面接口IAbstractBaseClass,在實現這接口的類中也必須有其內兩個方法
的實現代碼,不然同樣也會出錯。
四、禁止繼承
上面是「只能繼承」中建立對象。
下面是「禁止繼承」,用NotIneritable來講明此類,不許再進行繼承,到此爲止!
Public NotInheritable Class officeEmployee '指定基再也不作基類(即再也不向下派生)
不能被繼承的類有時被稱爲「密封」類
2、多接口
接口,如同外交家同樣,能夠與外界進行交流。
VB.net中,對象能夠有一個或多個接口。全部對象都有一個主接口或本地接口,接口由用Public聲明的方法、屬性、事件、字段。
除本地接口外,對象還可使用Implements來實現輔助接口。
一、對象接口
類中除Private聲明的外均可做本地接口。例:
'方法做爲接口 Public Sub AMethod() End Sub '屬性做爲接口 Public Property AProperty() As String End Property 'Event事件做接口 Public Event AEvent() '變量做接口 Public AInteger As Integer
注意:上面無實現代碼,由於接口只在於架子的聲明,其內的實現代碼並非接口的一部分。這是重要的區別!
由於將接口與實現代碼區分是面向對象程序設計的核心內容。
使用本地接口
一旦聲明瞭本地接口,就可在對象中用這些接口與外界產生交流。下面類中Pulbic方法,其對象就可直接用它與外界發生聯繫。
'============類的本地接口========= Public Class TheClass Public Sub DoSomething() '..... End Sub Public Sub DoOtherSomething() '....... End Sub End Class '==========主程序中使用這兩個接口======== Dim myObject As New TheClass myObject.DoSomething() myObject.DoOtherSomething()
二、輔助接口
在設計上,只有同類的對象纔有相同的本地接口,這有很大的限制。
若是把一組不一樣的對象,它們本地接口各不一樣,處理起來就麻煩了。
好比,對於產品 、顧客、發票三類對象,不具備天然的繼承關係,可是,咱們須要打印這三個信息,因而,
產生了另外一個概念「輔助接口」,也就平時說的接口,經過這個接口,使三者都可打印。
接口Interface是同Class,Modul同樣是同一級別的概念,它象抽象方法同樣並不具備實現代碼,實現代碼都在使用接口
的類中。這樣使用接口時,沒必要管是否是同一類型對象,都可正常運行。
(1)定義接口
用Interface來定義一個接口,經過添加模塊方式,在模塊外部添加接口代碼:
Public Interface IPrintableObject '接口定義(與Class,Module平級)內部做用域相同 Function Label(ByVal index As Integer) As String '故其前無Public,friend等限定 Function Value(ByVal index As Integer) As String ReadOnly Property Count() As Integer End Interface Module Interfaces End Module
接口定義包含在 Interface 和 End Interface 語句內。
在 Interface 語句後面,能夠選擇添加列出一個或多個被繼承接口的 Inherits 語句。 即接口能夠繼承。
在聲明中,Inherits 語句必須出如今除註釋外的全部其餘語句以前。
接口定義中其他的語句應該包括 Event、Sub、Function、Property、Interface、Class、Structure 和 Enum 語句。
接口不能包含任何實現代碼或與實現代碼關聯的語句,如 End Sub 或 End Property。
在命名空間中,默認狀況下,接口語句爲 Friend,但也能夠顯式聲明爲 Public 或 Friend。
在類、模塊、接口和結構中定義的接口默認爲 Public,但也能夠顯式聲明爲 Public、Friend、Protected 或 Private。
Shadows 關鍵字可應用於全部界面成員。 Overloads 關鍵字可應用於界面定義中聲明的 Sub、Function 和 Property 語句。
此外,Property 語句能夠具備 Default、ReadOnly 或 WriteOnly 修飾符。 不容許使用任何其餘修飾符:Public、Private、
Friend、Protected、Shared、Overrides、MustOverride 或 Overridable。
接口是一個數據類型,相似於類或結構(Struction)。由於能夠這樣定義這個類型的變量:
Private printable As IPrintableObject
但上面,都沒有實現的代碼,實現代碼都是在類中實現。因此接口是不能直接用New的。
(2)使用接口
用戶只須知道接口,沒必要了解對象內部細節,就可使用不一樣的對象。
窗體中添加方法:
Public Sub PrintObject(obj As IPrintableObject) '窗體內添加例程 Dim index As Integer For index = 0 To obj.Count Debug.Write(obj.Label(index) & ": ") Debug.WriteLine(obj.Value(index)) Next End Sub
而後窗體中添加按鈕,並添加代碼:
Private Sub ButtonPrint_Click(sender As Object,e As EventArgs) Handles ButtonPrint.Click Dim obj As New Employee() obj.EmployeeNumber = 123 obj.BirthDate = #1/1/1980# obj.HireDate = #1/1/1996# PrintObject(obj) End Sub
點擊運行,會提示錯誤:由於接口只是方法頭或事件頭,並無具體的實現代碼。所以還要在類中添加實現的代碼。
(3)實現接口
任何類(除抽象基類)均可以使用Implements來實現接口。
由於接口要用類的對象來傳遞,使得接口最後言之有物。而抽象基類是不能產生對象的,因此抽象基類是不能有接口的。
加入Implements回車後,會自動把接口各方法或事件的架子添加到類中,咱們只須在內加入實現代碼。
類中實現的方法、屬性等名稱,並不重要,重要的是參數的數據類型及返回值必須與接口定義的類型相匹配。
實現代碼以下:
'================Employee類中實現接口(鏈接到外部接口類型上)========= Implements IPrintableObject '這裏按回車後,自動添加Iprintableobject成員,來實現細節 '爲接口準備或要使用的字段 Private mLabels() As String = {"ID", "Age", "HireDate"} Private mBirthDate As Date Private mSalary As Double Public ReadOnly Property Count As Integer Implements IPrintableObject.Count Get Return UBound(mLabels) End Get End Property Private Function Label(index As Integer) As String Implements IPrintableObject.Label Return mLabels(index) End Function Public Function Value(index As Integer) As String Implements IPrintableObject.Value Select Case index Case 0 Return CStr(EmployeeNumber) Case 1 Return CStr(Age) Case Else Return Format(HireDate, "Short date") End Select End Function
注意:能夠看到實現方法等的後面有Implements IPrintableObject.Label,這相似於Handles,它也能夠經過用逗號把
一個接口的多個方法聯繫到一個方法中,或者多個接口的方法聯繫到一個方法中。
(實際上就是把函數地址與外界聯繫了起來,這樣使用這個地址,天然就調用了不一樣對象中的方法)
看一下整個接口的示意圖:
(4)重用 通用的實現代碼
輔助接口,能夠有幾個,幾個中能夠同一個方法,這個方法就成了通用的方法。
下面兩個接口有方法都聯繫到同一個方法Value(類Employe中)
'=========接口1,有Value================= Public Interface IPrintableObject Function Label(ByVal index As Integer) As String Function Value(ByVal index As Integer) As String ReadOnly Property Count() As Integer End Interface '========接口2,有GetValue=============== Public Interface IVales Function GetValue(ByVal index As Integer) As String End Interface '=======Employee中兩接口,同時關聯到Value函數上(函數簽名與上面相同參數)=========== Implements IPrintableObject Implements IVales Public Function Value(index As Integer) As String Implements IPrintableObject.Value, IVales.GetValue Select Case index Case 0 Return CStr(EmployeeNumber) Case 1 Return CStr(Age) Case Else Return Format(HireDate, "Short date") End Select End Function
能夠看到,其後用逗號表示,兩個接口都用到Value方法。
(5)合併接口、繼承
能夠同時合併輔助接口和繼承在。
當從一個實現接口的類繼承時,新的子類自動得到的接口和基類的實現代碼。
若是指定基類方法能夠重寫,則子類能夠重寫這些方法。
不只重寫基類主接口的實現代碼,並且也能夠重寫接口的實現代碼。
Public Overridable Function Value(ByVal index As Integer) As String Implements IPrintableObject.Value, IValues.GetValue
上面表示這個接口實現,是能夠被重寫的。
完整定義以下:
Public Overridable Function Value(index As Integer) As String Implements IPrintableObject.Value, IVales.GetValue Select Case index Case 0 Return CStr(EmployeeNumber) Case 1 Return CStr(Age) Case Else Return Format(HireDate, "Short date") End Select End Function
注意:因爲上面是Public,所以它在主接口(本地接口)中也是有效的。
而且它仍是兩個接口中的一部分,意味着能夠被三種方式訪問。
三種 方式訪問:
Dim emp As New Employee("Andy") Dim printable As IPrintableObject = emp Dim values As IVales = emp Debug.WriteLine(emp.Value(0)) Debug.WriteLine(printable.Value(0)) Debug.WriteLine(values.GetValue(0))
第一種:主接口(本地接口)
第二種:IprintableObject接口訪問
第三種:IValues接口訪問
這樣三種接口合併於一身,都在Value這個方法上。
要聲明接口方法的實現,可使用任何在實例方法聲明上合法的特性(包括 Overloads、Overrides、Overridable、Public、Private、Protected、Friend、Protected Friend、MustOverride、Default 和 Static)。
Shared 特性是不合法的,由於它定義類而不是實例方法。
-----------------------------------------------------------------------------------------------------------------------