c#提供面向對象的編程(包括封裝、繼承和多態)的完整支持。
1、“封裝”意味着將一組相關的屬性、方法和其他成員視為一個單元或對象。。
2、“繼承”描述基於現有類創建新類的能力。
3、多態意味着可以有多個可互換使用的類,即使每個類以不同的方式實現相同的屬性或方法
類和對象
“類”和“對象”分別描述對象的類型和類的實例。
定義類:
class Person
{
}
此外,c#在不需要支持繼承和多態性的“結構”類型
定義結構:
struct Person
{
}
類成員
每個類都具有不同的“類成員”。類成員包括屬性(用於描述類數據)、方法(用於定義類行為)和事件(用於在不同的類和對象中間提供通信)
屬性和字段
字段和屬性表示對象包含的信息。字段類似變量,可以直接讀取和設置它們,要注意訪問修飾符
定可以從類的實例中訪問的字段:
public class Person
{
string Name;
}
屬性具有get
和set
訪問器,它們對設置和返回值的方式提供更多控制
c#允許創建私有字段來存儲屬性值,或者使用自動實現的屬性,這些屬性都是在后台創建此字段,並為屬性過程提供基本邏輯。
定義自動實現的屬性:
class Person
{
public string Namge{get;set;}
}
如果需要執行一些其他操作來寫入和讀取屬性值,需要定義一個用於存儲屬性值的字段,並提供用於存儲和檢索該字段的基本邏輯:
class person
{
private string name;
public string Name
{
//將返回值存儲在字段中
get => name;
//將值存儲在字段中
set => name = value;
}
}
大多數屬性的方法或過程都是可以設置或可以獲取屬性值。但是可以創建只讀取或者只寫屬性來限制她們的修改或讀取。在c#中,可以忽略get
或set
屬性方法。但是,自動屬性的實現不能只寫。可以在包含類的構造函數中設置只讀自動實現屬性。
方法
“方法”是對象可以執行的操作。
定義類的方法:
class Person
{
public string SetName(string newName)
{
//寫入代碼
}
}
同一個方法,一個類型可以有多個實現,也叫“重載”,區別在於參數個數和參數類型的不同
重載方法:
class Person
{
public string SetName(string newName){}
public string SetName(int NewName){}
}
大多數情況下,方法是在類定義中聲明的。同時,c#還支持“擴展方法”,這種方法允許你將方法添加到實際類定義中之外的現有類中。
構造函數
構造函數是一種類的方法,它們在創建給定類型的對象時自動執行。構造函數通常用於初始化新對象的數據成員。構造函數只能在創建類時運行一次。
創建類,定義構造函數:
public class Person
{
public Person()
{
//寫入代碼
}
}
構造函數中的代碼始終在類中所有其他代碼運行之前運行,我們可以使用重載的方式創建多個構造函數重載。
創建類,定義多個構造函數實現重載:
public class Person
{
public Person()
{
//寫入代碼
}
public Person(string name)
{
//寫入代碼
}
}
事件
類或對象可以通過事件向其他類或對象通知發生的相關事項。發送(或引發)事件的類稱為“發行者”,接收(或處理)事件的類稱為“訂戶”。
1、若要在類中聲明事件,請使用 event
關鍵字。
2、若要引發事件,請調用事件委托。
3、若要訂閱事件,請使用 +=
運算符;若要取消訂閱事件,請使用 -=
運算符。
嵌套類
在一個類中定義的類稱為“嵌套類”。默認情況下,嵌套類是私有類
class Person
{
class GoodPeople
{
void Func()
{
Console.WriteLine("Func in GoodPeople")
}
}
}
如果要使用嵌套類,請使用嵌套容器類名稱,后接一個點,再接嵌套類名稱。
使用 Func
方法:
Person.GoodPeople gp = new Person.GoodPeoPle();
gp.Func();
訪問修飾符
public
:同一程序集中的任何其他代碼或引用該程序集的其他程序集都可以訪問該類型或成員。
private
:只有同一class或struct中的代碼可以訪問該類型或成員。
protected
:只有同一class或從該class派生的class中的代碼可以訪問該類型或成員。
internal
:同一程序集的代碼都可以訪問該類型或成員,但其他程序集中的代碼不可以。
protected internal
:該類型或成員可由對其聲明的程序集或另一程序集中的派生class
中的.任何代碼訪問
private protected
:只有在其聲明程序集內,通過相同class
中的代碼或派生自該class
的類型,才能訪問該類型或成員。
實例化類
若要創建對象,需要先實例化類。即創建類實例
創建類實例:
Person p = new Person();
實例化類之后, 可以為該實例的屬性和字段賦值,還可以調用類方法。
//為屬性賦值
p.Name = "張三";
//調用類方法
p.SetName("張三");
若要在類的實例化過程中為屬性賦值,請使用對象初始值設定項
Person p = new Person
{
Name = "張三";
}
靜態類和成員
類的靜態成員是指該類的所有實例共享的屬性、過程和字段。
定義靜態成員:
static class Person
{
public static string Name = "張三";
}
若要訪問靜態成員,請使用類的名稱,但不要創建類的對象。
訪問靜態成員:
Console.WriteLine(Person.Name); //張三
c#中的靜態類只有靜態成員,無法進行實例化。靜態成員也無法訪問非靜態屬性、字段和方法。
匿名類型
匿名類型使你無需為數據類型編寫類定義即可創建對象。
此時,編譯器將為你生成類。該類沒有可使用的名稱,且包含在聲明對象時指定的屬性。
創建匿名類型的實例:
var person = new
{
Name = "張三",
Age =18
}
繼承
通過繼承,可以創建一個新類,它重用、擴展和修改另一個類中定義的行為。其成員被繼承的類叫“基類”,繼承這些類成員的類叫做“派生類”。c#中所有的類都隱式繼承Object
類,該類為.NET層次結構,並為所有類提供低級別服務。
c#中不支持多重繼承,只能為一個派生類指定一個基類。
從基類繼承:
class Horse:Animal
{
}
默認情況下,可以繼承所有類。但是可以指定該類不能用作基類,也可以創建只能作為基類的類。
指定該類不能用作基類:
public sealed class Animal{}
指定只能作為基類:
public abstract class Animal{}
重寫
默認情況下,派生類繼承其基類的所有成員。若希望更改繼承成員的行為,則需要重寫該成員。即,可以在派生類中定義方法、屬性或事件達到新的實現。
用於控制重寫屬性和方法的修飾符:
c#修飾符 | 定義 |
---|---|
virtual | 允許在派生類中重寫成員 |
override | 重寫基類中定義的虛擬(可重寫)的成員 |
abstract | 要求在派生類中重寫類成員 |
new 修飾符 | 隱藏繼承基類的成員 |
接口
和類一樣,接口也定義了一系列屬性、方法和事件。但與類不同的是,接口並不提供實現。它們有類來實現,並從類定義為單獨的實體。接口表示一種約定,實現接口的類必須嚴格按其定義來實現接口的每個方面。
定義接口:
interface IPersonInterface
{
void GetName();
}
在類中實現接口:
class Person:IPersonInterface
{
void IPersonInterface.GetName()
{
//方法的實現
}
}
泛型
.NET Framework中的類、結構、接口和方法可以包括“類型參數”,該類型參數定義她們可以存儲或使用的對象類型。最常見的泛型示例是集合,從中可以指定要存儲在集合中的對象的類型。
定義泛型類:
public class Person<T>
{
public T Field;
}
創建泛型類的實例:
var person = new Person<string>();
person.Field = "張三";
委托
“委托”是一種類型,它定義方法簽名,可以提供對具有兼容簽名的任何方法的引用。你可以通過委托調用方法。委托用於將方法作為參數傳遞給其他方法。
事件處理程序就是通過委托調用方法。例如winfrom中的事件,窗口傳值
創建委托:
public delegate void PersonDelegate(string str);
創建對於委托指定的簽名相匹配的方法的引用:
class PersonClass
{
//方法匹配PersonDelegate的簽名
public static void PersonMethod(string message)
{
//寫入代碼
}
//實例化委托的方法
void PersonDelegate()
{
PersonDelegate pd = PersonMethod;//委托不要加括號
pd("person string");
}
}