VB.NET面向對象的程序設計語言
新版的Visual Basic 7也就是Visual Basic.NET,具有了面向對象語言的所有特征。即使以老vb程序員的角度看也對象的慨念并不完全是新的,但也要盡可能用面向對象的方式寫代碼。
如果你問一個面向對象程序設計高手什么是面向對象程序設計語言?那么你可能將聽到幾個絕對少不了的單詞,比如:類、接口、消息隱匿、封裝、繼承、多態等等。作為一個話題,面向對象語言不是那種很簡單只需要一兩天就能精通或者僅僅靠一次演講就能掌握的語言。要掌握面向對象程序語言你需要作在掌握理論的同時還要做大量的練習。本文表述了在vb.NET中運用面向對象原理編程的基本方法,本文沒有全面涉及vb.NET面向對象編程,本文僅僅是一個開始。
面向對象編程的優點
你是否對現代程序設計語言如此傾向面向對象編程感到驚訝?這有幾個原因,c++作為c的一個擴展發展起來支持面向對象編程技術,還有java這個星球上最受歡迎的編程語言也是一種面向對象的編程語言,然后,的確如此,vb發展成vb.NET后,也成為一種完全的面向對象的編程語言。有幾個好的原因導致了這個轉變。面向對象編程有幾個優點,比如:易于進行代碼維護,可擴展性好,代碼重用技術。這些優點是過程編程所沒有的。下面就談談面向對象技術的這些優點:
易于維護
在面向對象編程中模塊性是與生俱來的,實體表現為類和名字空間中具有相同功能的類,你可以向名字空間中增加一個類卻不會影響名字空間的其他成員。
可擴展性
面向對象編程支持擴展性,如果你有一個有某種功能的類,你可以很快的擴展這個類,創建另一個具有擴展功能的類。
代碼重用
自從功能被壓縮到一個類中并且類作為一個獨立的實體存在,提供一個類庫就變得非常容易了,事實是任何一個.NET Framework程序員都可以使用.NET Framework類庫,.NET Framework類庫是一個有豐富類的類庫,提供很強的功能,更可貴的是你可以很容易的擴展這些功能來滿足你的需要。
現在我們看看面向對象編程的特征的使用,首先從最簡單的開始。
類
在面向對象編程技術中類是主要的焦點,簡單的說,類是一種提供功能的數據類型。在vb.NET中宣布一個類要使用關鍵字class,比如,list1中就宣布了一個叫employee的類。
| Listing 1:Employee類 Class Employee End Class |
這是一個非常簡單的類。注意微軟推薦使用Pascal語言對類的命名規則。這就意味著類名的第一個字母必須是大寫,并且后來的并發連結詞的第個字母均為大寫。一個好的類名應該象這樣的GeneralManager, SmallDictionary, StringUtil。
類成員
一個類有象域、屬性、子程序和函數那樣的成員,比如,list2中employee類中有一個叫work的子程序
| Listing 2: Class Employee Public Sub Work () ' Do something here End Sub End Class |
子程序和函數又叫方法,方法的命名也遵循Pascal命名法。
另一個類成員類型是域,域的命名法則遵循camel-case法則,如一個好的域命名象salary 和quarterlyBonus這樣,在list3中我們在Employee類中添加了兩個域salary和quarterlyBonus
| Class Employee Dim salary As Decimal = 40000 Dim yearlyBonus As Decimal = 4000 Public Sub PrintSalary() ' print the salary to the Console System.Console.Write(salary) End Sub End Class |
對象實例
一個類是一個模板或代表實體的藍圖。由于要使用類的域、方法或其他成員,你第一次需要將類的觀念轉變為對象,這樣說吧,僅僅是跑車的藍圖是沒有用的,除非工程師將藍圖造成車,從另一個方面說,你駕駛的是車而不是藍圖。
在面向對象編程中,對象被稱為類的實例,因此創建一個對象的過程又被稱為實例化。
list4示范了實例化employee類
| Listing 4: 對象初始化 Class Employee Dim salary As Decimal = 40000 Dim yearlyBonus As Decimal = 4000 Public Sub PrintSalary() ' print the salary to the Console System.Console.Write(salary) End Sub End Class Module Module1 Public Sub Main() Dim anEmployee As Employee anEmployee = New Employee() anEmployee.PrintSalary() End Sub End Module |
Listing 4中的模塊Module1中提供了Main sub,在vb.NET程序中Main Sub是整個程序的入口,要編譯源程序,那么你就必須提供訪問Main Sub的途徑。
如果你沒有使用Visual Studio.NET,那么可以使用vbc.exe 編譯vb.NET源程序,vbc.exe 是在安裝.NET Framework時自動安裝的。舉個例子,當你把源代碼保存到文件Employee.vb中后,在Employee.vb相同的目錄下輸入vbc Employee.vb。
現在我們回到list4的代碼中,在Main sub中聲明了Employee類的對象變量,這個變量叫anEmployee.
| Dim anEmployee As Employee |
anEmployee初始化Employeer時必須使用關鍵字new.
| anEmployee = New Employee() |
現在我們有一個Employeer的對象,你可以使用它的功能了。在我們的例子中,調用了PrintSalary 方法。
| anEmployee.PrintSalary() |
你也可以把Main Sub放在類中,采用這種方法就不需要模塊,如list5中所示
| Listing 5: Moving the Main sub to the class itself Class Employee Dim salary As Decimal = 40000 Dim yearlyBonus As Decimal = 4000 Public Sub PrintSalary() ' print the salary to the Console System.Console.Write(salary) End Sub Public Shared Sub Main() Dim employee As Employee employee = New Employee() employee.PrintSalary() End Sub End Class |
注意在PrintSalary 方法中調用了System.Console.Write意味著調用了Console類的write方法并且Console類是System名字空間的一部分,關于名字空間我們將在后面講述。
名字空間
當寫.NET應用程序時,需要寫類和其他數據類型。為使應用程序更有條理,組織性更好,需要將他們聚合進名字空間中,這也是微軟用.NET Framework類庫的原因。微軟.NET Framework sdk文檔中的.NET Framework類庫中包含了80多個名字空間,包括常用的重要的名字空間,如System, System.IO, System.Drawing, System.Windows.Forms等等。舉例而言,在Employee類中的PrintSalary 方法,我們使用了system名字空間中的console類。
如果在程序中要經常使用一個名字空間,可以采取引用該名字空間的方法,這樣在每次調用其成員時就用不作重復寫名字空間了。例如你可以象下面這樣改寫list4和list5。
| Listing 6: Importing a namespace Imports System Class Employee Dim salary As Decimal = 40000 Dim yearlyBonus As Decimal = 4000 Public Sub PrintSalary() ' print the salary to the Console Console.Write(salary) End Sub Public Shared Sub Main() Dim employee As Employee employee = New Employee() employee.PrintSalary() End Sub End Class |
現在你可以在PrintSalary方法中使用名字空間而不用提及名字空間,因為名字空間已經引用了。
在不同的名字空間允許有相同名字的類,正確地引用一個類最普通的實踐是提到過的在類名前面的名字空間。如system名字空間中的Console的引用方法是:System.Console。
訪問類型
在很多例子中,當你寫出一個類后,你要將類提供給其他人訪問并且使用它的功能,他們可調用這個類的方法或者訪問類的域。面向對象編程的一大好處是可以對類成員的訪問進行限制。這就意味作,你能夠完全控制想顯示的內容。
你可以讓其他程序員訪問類中的方法,也可以不讓其他程序訪問,除非是來自類的內部。
在vb.NET中有幾個級別的訪問控制,詳細請看下表:
| Public | Public類成員沒有訪問限制。構造public類成員是在類成員名前面使用關鍵字public,所有人均可訪問public成員。例如,Employee類中的PrintSalary方法是一個公有方法,能夠被任何人和函數調用。 |
| Private | Private類成員只能被類內部訪問,使用Private關鍵字聲明私有化類成員。 |
| Protected | 保護成員能被類內部成員和他的繼承類訪問,使用關鍵字Protected定義保護成員。 |
| Friend | 友員訪問限制在聲明該類的程序中,使用關鍵字Friend聲明一個友員。 |
| Protected friend | protected和friend的結合。 |
在面向對象編程中不同的訪問限制提供了不同的信息隱藏方式,從另外一個方面來說,你可以保護你不想顯示的類成員變量。
靜態成員
我們再看一次list4,list5,list6中的Employee類,你可能會感到驚奇為什么我們在使用System.Console的write方法前沒有實例化這個類?這是因為在面向對象語言中有一種特殊的成員類型--靜態成員,在vb.NET中術語share與c++中的static有相同作用。
靜態意味作成員可以使用而用不作實例化,例如,在list7中SalaryLevel類提供了靜態域。
| Listing 7: Class SalaryLevel Public Shared Level1 As Decimal = 35000 Public Shared Level2 As Decimal = 40000 Public Shared Level3 As Decimal = 45000 Public Shared Level4 As Decimal = 50000 Public Shared Level5 As Decimal = 55000 Public Shared Level6 As Decimal = 60000 Public Shared Level7 As Decimal = 65000 Public Shared Level8 As Decimal = 70000 Public Shared Level9 As Decimal = 75000 Public Shared Level10 As Decimal = 80000 End Class |
那么我們可以在程序中使用這個類,如list8
| Listing 8: 使用類的靜態成員 Imports System Class SalaryLevel Public Shared Level1 As Decimal = 35000 Public Shared Level2 As Decimal = 40000 Public Shared Level3 As Decimal = 45000 Public Shared Level4 As Decimal = 50000 Public Shared Level5 As Decimal = 55000 Public Shared Level6 As Decimal = 60000 Public Shared Level7 As Decimal = 65000 Public Shared Level8 As Decimal = 70000 Public Shared Level9 As Decimal = 75000 Public Shared Level10 As Decimal = 80000 End Class Class Employee Dim yearlyBonus As Decimal = 4000 Public Sub PrintSalary() ' print the salary to the Console, use ' the static field of SalaryLevel Console.Write(SalaryLevel.Level4) End Sub Public Shared Sub Main() Dim employee As Employee employee = New Employee() employee.PrintSalary() End Sub End Class |
在Employee類的PrintSalary方法中,我們沒有創建SalaryLevel類的對象就使用了SalaryLevel的靜態域Level4 。類中非靜態成員稱為實例成員。
構造器
構造器是一種特殊的方法,在類初始化時必須使用構造器。在vb.NET中稱為new方法,但是正如你看到的,在前面的代碼中沒有一個new方法,是的,在沒有出現構造器時,vb.NET將為你創建一個。當你使用new關鍵字初始化一個對象時,類構造器被調用。當初始化對象時,你能夠提供初始化代碼以保證對象運行。
如果使用了關鍵字new,調用了類構造器,vb.NET將不再為你創造一個。
繼承
繼承是一個這樣的特征即允許你擴展類,如果你需要一些功能,你可以創造一個新類,如果你需要的功能中的部分功能已經能由一個已經存在的類提供了,你可以擴展原來的那個類來構建一個新類。那么你新建的這個類成為子類或者繼承類,原來的那個類稱為父類或者基類。擴充類的過程稱為擴展,有時術語subclass或inherit 用于描述擴展類的行為。在vb.NET中一個類只能有一個父類,多個父類的情況是不允許的。
在語法構成上,聲明一個擴展類在類名后面使用分號,分號后面使用Inherits和父類名,例如,擴展類Employee創建一個新類Manager,代碼如下
| Listing 9: Extending a class Imports System Class Employee Dim salary As Decimal = 40000 Dim yearlyBonus As Decimal = 4000 Public Sub PrintSalary() ' print the salary to the Console Console.Write(salary) End Sub End Class Class Manager: Inherits Employee End Class |
如果單詞Inherits 顯示在下一行,那么就不需要分號,如:
| Class Manager Inherits Employee End Class |
現在你可以初始化一個Manager對象,使用Manager對象中的成員,如下面的代碼
| Listing 10: 初始化Manager對象 Class Employee Public salary As Decimal = 40000 Public yearlyBonus As Decimal = 4000 Public Sub PrintSalary() ' print the salary to the Console Console.Write(salary) End Sub End Class Class Manager: Inherits Employee End Class Module Module1 Public Sub Main() Dim manager As Manager manager = New Manager() manager.PrintSalary() End Sub End Module |
下面的例子中顯示了在manage類中添加一個新方法PrintBonus
| Listing 11: Adding a method to the derived class Class Manager: Inherits Employee Public Sub PrintBonus() Console.Write(yearlyBonus) End Sub End Class |
注意成員訪問限制的使用,比如說如果設定yearlyBonus域為私有,那么manage類就不能訪問他,否則在編譯時就會得出錯誤結論。
繼承只是一個普通的實踐。事實上,.NET Framework類庫由不同層次的類組成,他們分別繼承于其他的類。比如,Windows.Forms名字空間中的button類是ButtonBase類的子類,而ButtonBase類本身又是Control類的子類,所有類最終都以System.Object作為他們的根,在.NET Framework類庫中System.Object又稱為根或者超類。
list12示范了繼承強大的能力。
| Listing 12: Extending System.Windows.Forms.Form Public Class MyForm : Inherits System.Windows.Forms.Form End Class |
聲明的這個空白類,經編譯執行后生成一個windows表單,你一行代碼都用不作寫就可以創建一個表單,這是因為myform繼承于System.Windows.Forms.Form,他也繼承了form的功能。
NotInheritable類
要使你的類不能夠被繼承,可以使用關鍵字NotInheritable。例如list13中的類Calculator就不能被繼承
| Listing 13: NotInheritable Class Calculator End Class |
如果試圖擴展這個類將產生一個編譯錯誤,那么既然繼承有這么大的好處,為什么要讓類不能被繼承呢?其中一個原因是你不想讓你的類被其他人擴展,另外一個原因是繼承類產生了更快的代碼。無論如何你應該謹慎的使用繼承類,因為它可能導致面向對象編程的主要目的的失敗。
還有一種類叫final類,他和其他面向對象語言中的final類相同。
結論
vb.NET支持眾多的面向對象的特征,本文顯示了vb.NET的不同特征,并提供了13個例子,可以以此開始學習vb.NET。