一、多型
多型是從繼承中引出來的概念,即不同的派生類對基類的相同方法表現出不同的行為,如下面例子中動物的游泳方法:
1 /// <summary> 2 /// 動物 3 /// </summary> 4 public class Animal 5 { 6 public string Swimming() 7 { 8 return "不會"; 9 } 10 } 11 /// <summary> 12 /// 雞 13 /// </summary> 14 public class Chicken : Animal 15 { 16 17 } 18 /// <summary> 19 /// 狗 20 /// </summary> 21 public class Dog : Animal 22 { 23 } 24 /// <summary> 25 /// 蛙 26 /// </summary> 27 public class Frog : Animal 28 { 29 }
當用戶使用派生類雞的游泳方法時,由于基類的游泳方法滿足雞的需求,則直接呼叫基類的游泳方法回傳不會;當用戶使用派生類狗和蛙的游泳方法時,由于基類的游泳方法的實作不滿足狗和蛙的需求,所以狗和蛙需要實作自己的邏輯,如何實作狗的狗刨和蛙的蛙泳?答案是重寫(使用關鍵字virtual和override在派生類中重新實作基類的同名方法),
1 public class Animal 2 { 3 //設計基類時對需要在派生類中重寫的方法使用virtual修飾,使用virtual修飾的方法叫做虛方法 4 public virtual string Swimming() 5 { 6 return "不會"; 7 } 8 } 9 public class Dog : Animal 10 { 11 //派生類若要重寫基類的方法,可使用override修飾與基類同名的方法,實作自己的行為,被override修飾的方法也可被重寫 12 public override string Swimming() 13 { 14 return "狗刨"; 15 } 16 } 17 public class Frog : Animal 18 { 19 //派生類若要重寫基類的方法,可使用override修飾與基類同名的方法,實作自己的行為,被override修飾的方法也可被重寫 20 public override string Swimming() 21 { 22 return "蛙泳"; 23 } 24 }
上面的例子中,不同的派生類(雞、狗、蛙)對基類(動物)的游泳方法表現出各自不同的結果,即類的多型特性,
也可以使用另一種方式覆寫來實作類的多型特性,即派生類使用new關鍵字來實作與基類同名方法的不同行為,
1 public class Animal 2 { 3 public string Swimming() 4 { 5 return "不會"; 6 } 7 } 8 public class Dog : Animal 9 { 10 //使用new關鍵字覆寫基類的同名方法,也可以使用到派生類的其他成員中 11 public new string Swimming() 12 { 13 return "狗刨"; 14 } 15 } 16 public class Frog : Animal 17 { 18 //使用new關鍵字覆寫基類的同名方法,也可以使用到派生類的其他成員中 19 public new string Swimming() 20 { 21 return "蛙泳"; 22 } 23 }
注:主要使用的情況是當我們沒有修改基類的權限又希望實作派生類的多型特性時,
二、C#關鍵字:base
在派生類的方法中使用“base.基類方法名”可以復用基類的方法,
三、C#關鍵字:sealed
由于被override修飾的方法是隱式可重寫的,所以當我們不希望被override修飾的方法被重寫時,可以使用sealed關鍵字防止被重寫,
1 public class Dog : Animal 2 { 3 //Dog類不希望自己的游泳方法被它的派生類重寫 4 public sealed override string Swimming() 5 { 6 return "狗刨"; 7 } 8 }
注:在防止被重寫中,sealed關鍵字必須與override關鍵字相同存在,
四、抽象類和抽象方法
當一個基類的作用只是為派生類提供公共成員,而無其他實際意義時,我們不希望用戶通過new關鍵字創建這個基類,可將基類設計成抽象類,這樣用戶就不能用new關鍵字創建它,使用abstract關鍵字修飾類可使其變成抽象類,
當抽象類的某個方法在派生類中表現出多型性時,這個方法的實作對派生來說是無用的,我們希望所有派生類必須重寫基類的這個方法,可將這個方法設計成抽象方法,這樣抽象類的抽象方法不用提供默認實作并且派生類必須使用override重寫此抽象方法,如果派生類不重寫這個抽象方法自身也將成為一個抽象類,使用abstract關鍵字修飾方法可使其變成抽象方法,
1 /// <summary> 2 /// 可調度溫度的電子設備 3 /// </summary> 4 public abstract class TemperatureElectric 5 { 6 protected int temperature; 7 8 public abstract int Up(); 9 10 public abstract int Down(); 11 } 12 /// <summary> 13 /// 空調 14 /// </summary> 15 public class AirConditioner : TemperatureElectric 16 { 17 public override int Up() 18 { 19 if (temperature < 30) 20 temperature += 1; 21 return temperature; 22 } 23 24 public override int Down() 25 { 26 if (temperature > 16) 27 temperature -= 1; 28 return temperature; 29 } 30 } 31 /// <summary> 32 /// 冰箱 33 /// </summary> 34 public class Refrigerator : TemperatureElectric 35 { 36 /// <summary> 37 /// 提升冷藏溫度 38 /// </summary> 39 public override int Up() 40 { 41 if (temperature < 7) 42 temperature += 1; 43 return temperature; 44 } 45 46 /// <summary> 47 /// 降低冷藏溫度 48 /// </summary> 49 public override int Down() 50 { 51 if (temperature > 3) 52 temperature -= 1; 53 return temperature; 54 } 55 }
五、幾種概念的對比
1、多載與重寫
多載和重寫的相同點在于他們都是對同名的方法使用,
多載和重寫的不同點:在使用范圍上,前者使用在單個類中,后者使用在兩個或多個有繼承關系的類中;在使用意圖上,前者是寫法上的簡化,后者是功能上的擴展,
2、重寫與覆寫
重寫與覆寫的相同點在于他們都是對基類同名方法的擴展,
重寫與覆寫的不同點在于,前者傾向于派生類的同名方法,后者傾向于基類的同名方法(在A a = new B(),B繼承于A的結構中);前者用于主動設計,后者用于被動修改,
1 public class RealizeObject 2 { 3 public void Realize() 4 { 5 //Dog是通過virtual和override重寫的Animal 6 Animal animal = new Dog(); 7 animal.Swimming();//輸出的狗刨 8 9 //Dog是通過new覆寫的Animal 10 Animal animal = new Dog(); 11 animal.Swimming();//輸出的不會 12 } 13 }
3、虛方法和抽象方法
虛方法與抽象方法的相同點在于他們都可以被重寫,
虛方法與抽象方法的不同點:在使用范圍上前者大于后者,前者使用在非密封類中,后者只能使用在抽象類中;在使用方式上,前者必須有實作部分,后者不能有實作部分;在派生類中,前者可重寫可不重寫,后者必須重寫,
4、抽象類與介面型別的區別(見C#介面型別)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/123943.html
標籤:C#
上一篇:Winform中實作跨表單獲取ZedGraph的ZedGraphControl控制元件物件
下一篇:MD5加密實作方法
