C#面向對象基本概念總結
快過年了,發一篇自己的復習總結。以下內容均是個人理解,如文章有幸被瀏覽,如有錯誤的地方歡迎大家提出,相互學習相互進步!
面向對象三大基本特征:封裝,繼承,多態
一、類
(對象聲明的三種方式:以普通基類身份聲明的變量並用基類對象賦值,以普通基類身份聲明的變量並用子類對象賦值,以子類身份聲明的變量並用子類對象賦值,抽象類聲明的變量必須由子類進行賦值(抽象類不能new))
1、類的分類:普通基類,抽象基類(abstract):抽象類天生(public)是給人繼承的,不能new(聲明對象),純抽象類(接口)
2、基本概念
- 類的統一成員分類:私有成員(僅在類的內部使用),共有成員(全宇宙可見),受保護成員(在類的內部和子類中使用)
- 子類繼承基類:子類可以繼承基類的共有成員和受保護成員,不能繼承私有成員
- 子類訪問基類成員時一般要使用base關鍵字
- 類成員的掃描順序:以誰身份聲明的變量就在誰身上開始掃描,先近後遠
- 類的訪問原則:類的外部只能訪問類的共有成員,子類可訪問基類的共有成員和受保護成員(繼承)
- 構造函數:函數名和類名相同(函數沒有返回類型,使用public修飾)
4、類的成員分類:
- 普通基類虛成員:類成員使用virtual 關鍵字修飾的為類的虛成員,可以被子類重寫,被子類重新的條件條件是子類的同名方法必須由override關鍵字修飾(使用情景:以基類身份聲明的變量,並以子類對象賦值,當調用方法時現在基類身上開始掃描,找到需要使用的方法並且方法是用virtual關鍵字修飾的虛成員,轉而向子類進行掃描,如果在子類身上找到對應的方法,並且該方法用override關鍵字進行修飾,那麽就調用子類方法,否則調用基類自己的方法)
- 抽象類成員:實例成員(在子類身上得到體現),抽象成員:抽象類中的抽象成員沒有具體的實現,也就是沒有方法體,就是沒有花括號。所以繼承抽象基類的子類必須實現基類的抽象成員,才能使抽基類的抽象成員得到體現
5、抽象類特別註意事項:繼承抽象類的子類必須實現抽象類的抽象成員,就是必須使用override(重寫)關鍵子修飾基類同名抽象成員
6、對繼承概念的認識:子類繼承了基類,在程序入口調用方法時,子類的構造函數繼承了基類的構造函數。以子類身份聲明的變量並以子類對象賦值,當調用子類中成員時,按照類的訪問規則,此時我們可以發現,基類通過子類繼承的構造函數,獲得了具體的成員
二、接口
interface聲明接口,接口是純抽象類,不能new。接口定義一些成員,不是用public關鍵字修飾,默認就是共有的////接口成員是純虛成員
主程序中調用接口時註意:
- 以接口身份聲明的變量必須以實現接口的類的對象進行賦值
- 以那個接口身份聲明的變量只能點出這個接口定義的成員(當一個類型繼承了多個接口時,使用這個類型調用接口時)
- 接口成員是方法的聲明(王老師名言)
接口的實現:實現接口的類必須實現接口成員
接口的顯示實現和隱式實現:當類實現單接口時一般使用隱式實現,實現多接口特別是多接口中定義了同名成員時要使用顯示實現(加接口名前綴)
£子類訪問基類:在子類的內部可以訪問基類共有成員和受保護成員,在子類的外部。子類對象只能訪問基類的共有成員(類的外部只能訪問類的共有成員)
三、繼承
子類繼承基類,基類的構造函數:聲明子類對象時,子類的構造函數要先給基類構造函數傳參,基類構造函數先於子類構造函數執行
四、函數的重載:一個類中,函數名相同簽名不同的方法稱為函數的重載,簽名指:返回類型,參數類型,參數數量,參數的順序
五、區別普通基類虛成員和抽象基類抽象成員
- 普通基類虛成員使用virtual關鍵字修飾,其子類可以不必重寫(override)其虛成員
- 抽象基類抽象成員使用abstract關鍵字修飾,其抽象成員沒有具體的實現必須由子類來實現(override)
六、抽象基類多態的理解:子類繼承抽象基類使用基類作為一個大的主題,使用引擎類對基類的訪問,實現對每個繼承基類子類成員的調用(聯想動物代碼)
七、接口(純抽象類)和抽象類的異同:
- 異:接口是純抽象類,不能有任何實例成員,抽象類可以存在實例成員,並在子類中可以得到體現。接口使用關鍵字interface修飾,抽象類使用abstract修飾,接口的成員不使用任何的修飾字,抽象類抽象成員使用abstract進行修飾,子類繼承抽象基類必須重寫基類中的抽象成員(override)
- 同:接口的成員(方法),抽象類的抽象成員不能具體的實現,也就是沒有方法體,也就是沒有花括號,只需要聲明
八、接口實現多態(多變性、靈活性):語法級別優化代碼
聲明:以下代碼中出現的中文全是本人自稱為新時代“愛因斯坦”的東北老師的作品?
1、聲明接口,實現接口的類
1 namespace OODemo
2 {
3 //接口是純抽像類,不能有任何實例成員,接口的成員是方法的聲明
4 public interface IWeapon
5 {
6 //接口成員天生就是public所以你不能加public關鍵字
7 void Fire();
8 }
9 //實現接口的類必須實現接口成員
10 public class Gun : IWeapon
11 {
12 public void Fire()
13 {
14 Console.WriteLine("pa peng pa peng");
15 }
16 }
17
18 public class Sword : IWeapon
19 {
20 public void Fire()
21 {
22 Console.WriteLine("七劍下天山");
23 }
24
25 }
26
27 public class Tank : IWeapon
28 {
29 public void Fire()
30 {
31 Console.WriteLine("壓死你");
32 }
33 }
34
35 public class Xiaomugun : IWeapon
36 {
37 public void Fire()
38 {
39 Console.WriteLine("紮死你");
40 }
41 }
42 }
2、使用一個“引擎類”:Engine作為中間層以接口類型的變量為參數
1 namespace OODemo 2 { 3 4 class Engine 5 { 6 //耦合//解耦//分離關註點 7 public static void Play(IWeapon w) 8 { 9 w.Fire(); 10 } 11 } 12 }
3、使用實現了接口的類作為參數,調用各自實現接口成員的功能
1 namespace OODemo 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 Engine.Play(new Gun()); 8 9 Engine.Play(new Tank()); 10 Engine.Play(new Sword()); 11 Engine.Play(new Xiaomugun()); 12 } 13 14 public void Fire() 15 { 16 Console.WriteLine("七劍下天山"); 17 } 18 } 19 }
九、抽象類實現多態:方式和接口實現多態的相似,一下直接書寫舉例代碼(接口和抽象類實現多態的異同沒弄明白)
問題:接口和抽象類都可以實現多態,只需要有一個就可以了,要麽接口要麽抽象類,為什麽兩個都存在?那麽那個更好些?
1、聲明三個基礎類繼承抽象類Animal 抽象類: namespace OODemo { abstract class Animal { public abstract void Play(); } } 基礎類: namespace OODemo { class Cat : Animal { public override void Play() { Console.WriteLine("喵喵喵,快給我條魚"); } } class Dog : Animal { public override void Play() { Console.WriteLine("汪汪汪,快給我根肉骨頭"); } } class Mouse : Animal { public override void Play() { Console.WriteLine("zhi zhi zhi"); } } } 使用引擎類 namespace OODemo { class Engine { public void Play(Animal a) { a.Play(); } } } 調用 namespace OODemo { class Program { static void Main(string[] args) { //有爽,啰嗦,玩就玩嗎,你還playdog,playcat的 Engine e = new Engine(); //e.Play(new Animal()); Dog dd = new Dog(); e.Play(dd); ////dd.PlayD(); Cat cc = new Cat(); e.Play(cc); ////cc.PlayC(); Snake sn = new Snake(); e.Play(sn); Mouse m = new Mouse(); e.Play(m); } } }
靜態類,靜態方法
C#面向對象基本概念總結