C# 學習筆記(4) 類
面向對象程式設計主要是為了寫出一個通用的代碼,屏蔽差異,友善開發大型項目。類就是面向對象程式設計的核心之一。和C語言的結構體相比,結構體擁有的功能,類統統都有,除此之外,類還有許多新特性。
類的構成
[其他修飾符] [通路修飾符] class 類名
{
字段;
屬性;
方法;
構造函數;
析構函數;
}
字段
存放類的私有資料,通常隻能被類的屬性通路。
屬性
保護字段,對字段的指派和取值進行限定。例如有一個學生類,類中有成績這個字段,類外隻可以擷取到成績的等級–優良中差,這時就可以給這個字段加上一個屬性,通過通路屬性間接通路成績字段。為了保證程式封裝性,類外一般是不允許通路類内的字段的,一般字段和屬性是成對出現的。
public class Student
{
int _Score; //成績字段
public string Score //成績屬性
{
get
{
if(_Score < 60)
{
return "差";
}
else if(_Score < 80)
{
return "中";
}
else if(_Score < 90)
{
return "良";
}
else
{
return "優";
}
}
set
{
_Score = int.Parse(value);
}
}
}
屬性的本質就是兩個方法,一個叫get()一個叫set()。
既有get()也有set()我們誠之為可讀可寫屬性。
隻有get()沒有set()我們稱之為隻讀屬性
沒有get()隻有set()我們稱之為隻寫屬性
方法
方法也就是C語言中的函數,面向對象裡面叫方法。
- C語言中,函數名字不能重複,而C#中允許方法名重複(方法重載),不過要求方法參數要麼個數不同,要麼類型不同。
public class Student
{
int _Score; //成績字段
public string Score //成績屬性
{
get
{
if(_Score < 60)
{
return "差";
}
else if(_Score < 80)
{
return "中";
}
else if(_Score < 90)
{
return "良";
}
else
{
return "優";
}
}
set { _Score = int.Parse(value); }
}
//三個方法名字都叫Learn 方法1、2參數個數相同但是類型不同 方法1、3參數類型相同但是個數不同
public void Learn(string subject, int time)
{
Console.WriteLine("學習{0}科目, 學習時長:{1}", subject, time);
}
public void Learn(string subject1, string subject2)
{
Console.WriteLine("學習{0}科目, 學習{1}科目", subject1, subject2);
}
public void Learn(string subject, int time, float ratio)
{
Console.WriteLine("學習{0}科目, 學習時長:{1}, 學習效率:{2}", subject, time, ratio);
}
}
構造函數
作用:幫助我們初始化對象(給對象的屬性指派)
構造函數是一個特殊的方法:
1)、構造函數沒有傳回值,連void也不能寫。
2)、構造函數的名稱必須跟類名一樣。
- 建立對象的時候會執行構造函數
- 構造函數是可以有重載的。
類當中會有一個預設的無參數的構造函數,當你寫一個新的構造函數之後,不管是有參數的還是
無參數的,那個預設的無參數的構造函數都被幹掉了。
public class Student
{
int _Score; //成績字段
public string Score //成績屬性
{
get
{
if(_Score < 60)
{
return "差";
}
else if(_Score < 80)
{
return "中";
}
else if(_Score < 90)
{
return "良";
}
else
{
return "優";
}
}
set
{
_Score = int.Parse(value);
}
}
//預設構造函數 也可以自己添加參數和方法體
public Student()
{
}
}
析構函數
作用:析構函數(destructor) 與構造函數相反,當對象脫離其作用域時(例如對象所在的函數已調用完畢),系統自動執行析構函數。析構函數往往用來做“清理善後” 的工作(例如在建立對象時用new開辟了一片記憶體空間,應在退出前在析構函數中用delete釋放)。
-
差別于構造函數。它不能帶任何參數,也沒有傳回值(包括void類型)。隻能有一個析構函數,不能重載。如果使用者沒有編寫析構函數,編譯系統會自動生成一個預設的析構函數,它也不進行任何操作。
析構函數是一個特殊的方法:
1)、析構函數不能被繼承或重載。
2)、析構函數不能被使用者調用。
3)、析構函數不能帶修飾或參數。
4)、如果沒有析構函數系統會自動生成一個空的析構函數,對象使用的資源将有由GC Garbage Collection垃圾回收器回收(如果使用者想要自己釋放資源,則要自行 編寫析構函數)
public class Student
{
int _Score; //成績字段
public string Score //成績屬性
{
get
{
if(_Score < 60)
{
return "差";
}
else if(_Score < 80)
{
return "中";
}
else if(_Score < 90)
{
return "良";
}
else
{
return "優";
}
}
set
{
_Score = int.Parse(value);
}
}
//預設構造函數 也可以自己添加參數和方法體
public Student()
{
}
//預設析構函數 也可以自己添加方法體
~Student()
{
}
}
修飾符
通路修飾符
- public :公開的公共的
- private:私有的,隻能在目前類的内部通路
- protected:受保護的,隻能在目前類的内部以及該類的子類中通路。
- internal:隻能在目前項目中通路。在同一個項目中,internal和public的權限是一樣。
- protected internal:protected+internal
1)、能夠修飾類的通路修飾符隻有兩個:public、internal。
2)、在繼承中,當可通路性不一緻時,
子類的通路權限不能高于父類的通路權限,否則會暴漏父類的成員。
其他修飾符
- partial部分類
在合作開發時,一個類可能由多個人寫,每個人都寫在不同的檔案中,這時可以使用partial來修飾類,表示目前隻是該類的一部分。
- sealed密封類
丁克,不能被繼承
- static
靜态和非靜态的差別
1)、在非靜态類中,既可以有執行個體成員,也可以有靜态成員。
2)、在調用執行個體成員的時候,需要使用對象名.執行個體成員;
在調用靜态成員的時候,需要使用類名.靜态成員名;
總結:靜态成員必須使用類名去調用,而執行個體成員使用對象名調用。
靜态函數中,隻能通路靜态成員,不允許通路執行個體成員。
執行個體函數中,既可以使用靜态成員,也可以使用執行個體成員。
靜态類中隻允許有靜态成員,不允許出現執行個體成員。
使用:
1)、如果你想要你的類當做一個"工具類"去使用,這個時候可以考慮将類寫成靜态的。
2)、靜态類在整個項目中資源共享。
隻有在程式全部結束之後,靜态類才會釋放資源。