物件導向程式設計 (C# 與 Visual Basic)
.NET Framework 中的所有 Managed 語言 (如 Visual Basic 和 C#) 都支援完整的物件導向程式設計,包括封裝、繼承和多型。
「封裝」指的是將一組相關的屬性、方法和其他成員,視為單一單位或物件。
「繼承」則是描述依據現有類別來建立新類別的能力。
「多型」指的是您可以有多個交替使用的類別,即使每個類別是以不同的方式來實作相同的屬性或方法。
本節將說明下列概念:
類別與物件
類別成員
屬性與欄位
方法
建構函式
解構函式
事件
巢狀類別
存取修飾詞與存取層級
執行個體化類別
靜態 (共用) 類別與成員
匿名型別
繼承
- 覆寫成員
介面
泛型
委派
類別與物件
「類別」(Class) 和「物件」(Object) 一詞有時會交換使用,但事實上,類別說的是物件的「型別」(Type),而物件則是類別之可使用的「執行個體」(Instance)。因此,建立物件的動作稱為「執行個體化」(Instantiation)。再以藍圖作比喻,若類別是藍圖,物件就是根據藍圖所蓋的建築物。
若要定義類別:
Class SampleClass
End Class
class SampleClass
{
}
Visual Basic 和 C# 都會提供輕量版的類別,稱為「結構」(Structure),當您必須建立龐大物件陣列而不想要使用太多記憶體時,這個結構會很有用。
若要定義結構:
Structure SampleStructure
End Structure
struct SampleStruct
{
}
如需詳細資訊,請參閱:
Visual Basic
C#
類別成員
每個類別都有不同的「類別成員」(Class Member),包括描述類別資料的屬性、定義類別行為的方法,以及提供不同類別與物件之間通訊的事件。
屬性與欄位
欄位和屬性表示物件包含的資訊。欄位就像是變數,可直接讀取或設定。
若要定義欄位:
Class SampleClass
Public SampleField As String
End Class
Class SampleClass
{
public string sampleField;
}
屬性具有取得和設定程序,讓您更容易控制設定與傳回數值的方式。
C# 和 Visual Basic 都允許您建立私用欄位來儲存屬性值,或是使用所謂的自動實作屬性,自動在幕後建立此欄位並提供屬性程序的基本邏輯。
若要定義自動實作屬性:
Class SampleClass
Public Property SampleProperty as String
End Class
class SampleClass
{
public int SampleProperty { get; set; }
}
如果您需要執行某些額外作業來讀取和寫入屬性值,請定義用來儲存屬性值的欄位,並提供儲存和擷取這個欄位的基本邏輯:
Class Samplelass
Private m_Sample As String
Public Property Sample() As String
Get
' Return the value stored in the field.
Return m_Sample
End Get
Set(ByVal Value As String)
' Store the value in the field.
m_Sample = Value
End Set
End Property
End Class
class SampleClass
{
private int _sample;
public int Sample
{
// Return the value stored in a field.
get { return _sample; }
// Store the value in the field.
set { _sample = value; }
}
}
大部分屬性都具有方法或程序,可以設定及取得屬性值。但是您可以建立唯讀或唯寫屬性來限制不得修改或讀取。在 Visual Basic 中,您可以使用 ReadOnly 和 WriteOnly 關鍵字。在 C# 中,則可以省略 get 或 set 屬性方法。不過,在 Visual Basic 和 C# 中,自動實作的屬性都不可以是唯讀或唯寫。
如需詳細資訊,請參閱:
Visual Basic
C#
方法
「方法」(Method) 是物件可執行的動作。
注意事項 |
---|
在 Visual Basic 中,有兩個建立方法的方式:如果方法沒有傳回值,即使用 Sub 陳述式;如果有傳回值,則使用 Function 陳述式。 |
若要定義類別的方法:
Class SampleClass
Public Function SampleFunc(ByVal SampleParam As String)
' Add code here
End Function
End Class
class SampleClass
{
public int sampleMethod(string sampleParam)
{
// Insert code here
}
}
類別可以有同一個方法的多個實作或「多載」(Overload),但是這些實作的參數個數和參數型別並不相同。
若要多載方法:
Overloads Sub Display(ByVal theChar As Char)
' Add code that displays Char data.
End Sub
Overloads Sub Display(ByVal theInteger As Integer)
' Add code that displays Integer data.
End Sub
public int sampleMethod(string sampleParam) {};
public int sampleMethod(int sampleParam) {}
在多數情況下,您是在類別定義中宣告方法。不過,Visual Basic 和 C# 也都支援「擴充方法」(Extension Method),允許您在現有類別的實際定義之外將方法加入至類別。
如需詳細資訊,請參閱:
Visual Basic
C#
建構函式
建構函式是類別方法,會在建立指定型別的物件時自動執行。建構函式通常用來初始化新物件的資料成員,而且只能在建立類別時執行一次。此外,建構函式中的程式碼永遠會在類別中的任何其他程式碼執行之前執行。不過,就和其他任何方法一樣,您可以建立多個建構函式多載。
若要定義類別的建構函式:
Class SampleClass
Sub New(ByVal s As String)
// Add code here.
End Sub
End Class
public class SampleClass
{
public SampleClass()
{
// Add code here
}
}
如需詳細資訊,請參閱:
Visual Basic
Sub New
C#
解構函式
解構函式是用來解構類別的執行個體。在 .NET Framework 中,記憶體回收行程會自動管理應用程式中 Managed 物件的記憶體配置及釋放。不過,您可能仍然需要解構函式來清除應用程式建立的任何 Unmanaged 資源。一個類別只能有一個解構函式。
如需 .NET Framework 中有關解構函式和記憶體回收行程的詳細資訊,請參閱記憶體回收。
事件
事件可讓類別或物件在某些相關的事情發生時,告知其他類別或物件。傳送 (或引發) 事件的類別稱為「發行者」(Publisher),而接收 (或處理) 事件的類別則稱為「訂閱者」(Subscriber)。如需事件以及如何引發和處理事件的詳細資訊,請參閱處理和引發事件。
Visual Basic
若要宣告事件,請使用 Event 陳述式。
若要引發事件,請使用 RaiseEvent 陳述式。
若要以宣告的方式指定事件處理常式,請使用 WithEvents (Visual Basic) 陳述式和 Handles 子句 (Visual Basic) 子句。
若要能夠動態地加入、移除及變更與事件相關聯的事件處理常式,請將 AddHandler 陳述式和 RemoveHandler 陳述式與 AddressOf 運算子 (Visual Basic)搭配使用。
C#
若要宣告類別中的事件,請使用 event (C# 參考) 關鍵字。
要引發事件,請叫用事件委派。
若要訂閱事件,請使用 += 運算子;若要取消訂閱事件,則使用 -= 運算子。
巢狀類別
在類別中定義的另一個類別即稱為「巢狀」(Nested) 類別。巢狀類別預設為私用。
Class Container
Class Nested
' Add code here.
End Class
End Class
class Container
{
class Nested
{
// Add code here.
}
}
若要建立巢狀類別的執行個體,請使用容器類別名稱,後面加上點號,再接著巢狀類別名稱,如下所示:
Dim nestedInstance As Container.Nested = New Container.Nested()
Container.Nested nestedInstance = new Container.Nested()
存取修飾詞與存取層級
所有類別及類別成員都可以使用「存取修飾詞」(Access Modifier),指定要提供給其他類別的存取層級。
下列為可用的存取修飾詞:
Visual Basic 修飾詞 |
C# 修飾詞 |
定義 |
---|---|---|
型別或成員可由相同組件或參考該組件的另一個組件中的任何其他程式碼存取。 |
||
型別或成員只能由相同類別中的程式碼存取。 |
||
型別或成員只能由相同類別中,或是衍生類別中的程式碼存取。 |
||
型別或成員可由相同組件中的任何程式碼存取,但是不包括其他組件中的程式碼。 |
||
Protected Friend |
protected internal |
型別或成員可由相同組件中的任何程式碼,或是其他組件中的任何衍生類別存取。 |
如需詳細資訊,請參閱Visual Basic 中的存取層級與存取修飾詞 (C# 程式設計手冊)。
執行個體化類別
若要建立物件,您必須將類別執行個體化,或是建立類別執行個體。
Dim sampleObject as New SampleClass()
SampleClass sampleObject = new SampleClass();
將類別執行個體化之後,您就可以將值指派給執行個體的屬性和欄位,並叫用類別方法。
' Set a property value.
sampleObject.SampleProperty = "Sample String"
' Call a method.
sampleObject.SampleMethod()
// Set a property value.
sampleObject.sampleProperty = "Sample String";
// Call a method.
sampleObject.sampleMethod();
若要在類別執行個體化期間將值指派給屬性,請使用物件初始設定式:
Dim sampleObject = New SampleClass With
{.FirstProperty = "A", .SecondProperty = "B"}
// Set a property value.
SampleClass sampleObject = new SampleClass
{ FirstProperty = "A", SecondProperty = "B" };
如需詳細資訊,請參閱:
Visual Basic
C#
靜態 (共用) 類別與成員
類別的靜態成員 (在 Visual Basic 中為共用成員) 是類別所有執行個體共用的屬性、程序或欄位。
若要定義靜態 (共用) 成員:
Class SampleClass
Public Shared SampleString As String = "Sample String"
End Class
static class SampleClass
{
public static string SampleString = "Sample String";
}
若要存取靜態 (共用) 成員,請使用類別的名稱,但不要建立這個類別的物件:
MsgBox(SampleClass.SampleString)
Console.WriteLine(SampleClass.SampleString);
C# 中的靜態 (共用) 類別及 Visual Basic 中的模組只有靜態 (共用) 成員,而且無法執行個體化。靜態 (共用) 成員也無法存取非靜態 (非共用) 屬性、欄位或方法
如需詳細資訊,請參閱:
Visual Basic
C#
匿名型別
使用匿名型別建立物件時,您不需要撰寫資料型別的類別定義,編譯器 (Compiler) 會自動幫您建立類別 (Class)。這個類別沒有可使用的名稱,但是包含您在宣告物件時指定的屬性。
若要建立匿名型別的執行個體:
' sampleObject is an instance of a simple anonymous type.
Dim sampleObject =
New With {Key .FirstProperty = "A", .SecondProperty = "B"}
// sampleObject is an instance of a simple anonymous type.
var sampleObject =
new { FirstProperty = "A", SecondProperty = "B" };
如需詳細資訊,請參閱:
Visual Basic:匿名型別 (Visual Basic)
C#: 匿名型別 (C# 程式設計手冊)
繼承
繼承可讓您建立新類別以重複使用、擴充和修改其他類別中定義的行為。成員被繼承的類別稱為「基底類別」(Base Class),而繼承這種成員的類別即稱為「衍生類別」(Derived Class)。不過,C# 及 Visual Basic 中的所有類別都隱含繼承自 Object 類別,這個類別支援 .NET 類別階層架構,並為所有類別提供低階服務。
注意事項 |
---|
在.NET框架中的Managed 語言不支援多重繼承,.也就是說.你只可以指定一個基礎的class給一個衍生的class |
若要繼承基底類別:
Class DerivedClass
Inherits BaseClass
End Class
class DerivedClass:BaseClass{}
所有類別預設都可以被繼承。不過,您可以指定類別是否不得當做基底類別,或是建立只能當做基底類別的類別。
若要指定類別不得當做基底類別使用:
NotInheritable Class SampleClass
End Class
public sealed class A { }
若要指定類別只能當做基底類別且無法執行個體化:
MustInherit Class BaseClass
End Class
public abstract class B { }
如需詳細資訊,請參閱:
Visual Basic
C#
覆寫成員
衍生類別預設會從其基底類別繼承所有成員。如果想要變更所繼承成員的行為,您必須覆寫這個成員。也就是說,您可以定義衍生類別中方法、屬性或事件的新實作。
下列修飾詞是用來控制如何覆寫屬性及方法:
Visual Basic 修飾詞 |
C# 修飾詞 |
定義 |
---|---|---|
允許在衍生類別中覆寫類別成員。 |
||
覆寫在基底類別中定義的虛擬 (可覆寫) 成員。 |
||
不支援 |
防止在繼承的類別中覆寫成員。 |
|
要求在衍生類別中覆寫類別成員。 |
||
隱藏繼承自基底類別的成員。 |
介面
介面就像類別,可定義屬性、方法和事件集。但與類別不同的是,介面並不提供實作。介面是由類別實作,並定義為與類別不同的實體。介面就代表著一種合約,因為實作介面的類別必須完全依介面的定義來實作這個介面的各個方面。
若要定義介面:
Public Interface ISampleInterface
Sub DoSomething()
End Interface
interface ISampleInterface
{
void doSomething();
}
若要在類別中實作介面:
Class SampleClass
Implements ISampleInterface
Sub doSomething
' Method implementation.
End Sub
End Class
class SampleClass : ISampleInterface
{
void ISampleInterface.SampleMethod()
{
// Method implementation.
}
}
如需詳細資訊,請參閱:
Visual Basic
C#
泛型
.NET Framework 中的類別、結構、介面和方法可以具有「型別參數」(Type Parameter),這些參數會定義可儲存或使用之物件的型別。泛型最常見的範例是集合,您可以在其中指定要儲存於集合之物件的型別。
若要定義泛型類別:
Class SampleGeneric(Of T)
Public Field As T
End Class
Public class SampleGeneric<T>
{
public T Field;
}
若要建立泛型類別的執行個體:
Dim sampleObject As New SampleGeneric(Of String)
sampleObject.Field = "Sample string"
SampleGeneric<string> sampleObject = new SampleGeneric<string>();
sampleObject.Field = "Sample string";
如需詳細資訊,請參閱:
委派
「委派」(Delegate) 是定義方法簽章的型別,可以提供任何具有相容簽章之方法的參考。您可以透過委派叫用 (Invoke) 或呼叫方法。委派可以用來將方法當做引數傳遞給其他方法。
注意事項 |
---|
事件處理常式就是透過委派叫用的方法。如需將委派用於事件處理的詳細資訊,請參閱事件和委派。 |
若要建立委派:
Delegate Sub SampleDelegate(ByVal str As String)
public delegate void SampleDelegate(string str);
若要建立與委派所指定簽章相符之方法的參考:
Class SampleClass
' Method that matches the SampleDelegate signature.
Sub SampleSub(ByVal str As String)
' Add code here.
End Sub
' Method that instantiates the delegate.
Sub SampleDelegateSub()
Dim sd As SampleDelegate = AddressOf SampleSub
sd("Sample string")
End Sub
End Class
class SampleClass
{
// Method that matches the SampleDelegate signature.
public static void sampleMethod(string message)
{
// Add code here.
}
// Method that instantiates the delegate.
void SampleDelegate()
{
SampleDelegate sd = sampleMethod;
sd("Sample string");
}
}
如需詳細資訊,請參閱:
Visual Basic
C#