在一個類前加“abstract”關鍵字,此類就成為抽象類。
對應的,在一個方法前加“abstract”關鍵字,此方法就成為抽象方法。
abstract class Fruit //抽象類 { public abstract void GrowInArea();//抽象方法 }
注意抽象方法不能又實現代碼,在方法名后直接跟一個分號。
抽象類專用於派生出子類,子類必須實現抽象類中所生命的方法。否子子類仍是抽象類。
抽象類一般用於表達一種比較抽象的事物,比如說“水果”,而抽象方法則說明此抽象類應該具有的某種特性。比如Fruit類中有一個抽象方法GrowInArea(),說明水果一定有一個最適合其生長的地區,但不同的水果生長是不同的。
從統一抽象類中繼承的子類擁有相同的方法(及抽象類所定義的抽象方法),但這種方法的具體代碼每個類都可以不一樣。
如:
class Apple:Fruit //蘋果類 { public override void GrowInArea() { Console.WriteLine("南北方都可以種植。"); } } class Pineapple:Fruit //菠蘿 { public override void GrowInArea() { Console.WriteLine("只在南方種植。"); } }
上述代碼中的override關鍵字,說明子類重寫了基類的抽象方法,抽象類不能創建對象,一般用它來引用子類對象。
Fruit f; f=new Apple(); f.GrowInArea(); f=new Pineapple(); f.GrowInArea();
結果:
南北方都可以種植。
只在南方種植。
上述幾段代碼所說,f 所引用的對象不同而輸出不同的結果。
可以按照以下公式編寫代碼:
抽象類 抽象類變量名=new 繼承自此抽象類的具體子類名();
一個抽象類中可以包含非抽象的方法和字段。因此:
包含抽象方法的類一定是抽象類,但抽象類中的方法不一定是抽象方法。
抽象屬性
abstract class Parent { public abstract String Message //抽象屬性 { get;set; } } class Child:Parent { private String _msg; public override String Message { get { return _msg; } set { _msg=value; } } }
代碼使用:
Parent p =new Child(); p.Message="Hello";
接口
舉個例子
鴨子是一種鳥,會游泳,同時又是一種食物。
如何在面向對象的程序中表達這種關系?
因為在C#中無法繼承兩個類,所以為了解決這一問題,C#引入了接口(interface),並規定”一個類可以實現多個接口“。
關鍵在interface用於定義接口
//定義兩個接口 public interface ISwim { void Swim(); } public interface IFood { void Cook; }
接口可以看成一種”純“的抽象類,接口的所有方法都是抽象方法。
//定義一個抽象類 public abstract class Bird { public abstract void Fly(); } //繼承自一個抽象類,實現兩個接口 public class Duck:Bird,IFood,ISwim { //實現ISwim接口 public void Swim() { Console.WriteLine("是鴨子就會游泳。"); } //實現IFood接口 public void Cook() { Console.WriteLine("鴨子經常被燒烤。"); } //實現抽象類Brid中的抽象方法 public override void Fly() { Console.WriteLine("只有野鴨才會飛"); } }
使用:
接口類型名 變量名=new 實現了接口的類型名();
代碼:
static void Main(string[] args) { Duck d =new Duck(); //Duck對象d可以使用3中方法: //1.自行定義的; //2.父類定義的 //3.接口定義的 d.Fly(); d.Cook(); d.Swim(); //將子類(Duck)對象賦給基類變量 Bird b=d; //現在只能使用基類定義的Fly()方法 b.Fly(); //將Duck對象賦給ISwim接口變量 ISwim s=d; //現在只能使用接口定義的Swim()方法 s.Swim(); //將Duck對象賦給另一個實現的接口IFood接口變量 IFood f=d; //現在只能使用接口定義的Cook()方法 f.Cook(); }
雖然程序中使用都只有一個Duck對象,但將其賦值給不同類型的變量后,其可以使用的方法是不一樣的。
顯示實現接口
當某個類實現多個接口,創建一個此類的對象之后,通過引用這個對象的對象變量可以訪問其所有的公有方法(包括自身的公有方法以及有接口定義的公有方法)。這種情況下,就分不清哪些方法是由接口提供,那些是有自己定義的。而C#提供餓了一種”顯示接口“實現機制,區分這兩種情況。
interface IMyInterface { void func(); } public class A:IMyInterface { void IMyInterface.func() { //... } public void func2() { //... } }
用粗體表示的就是C#對接口IMyInterface的顯示實現方式。
當類A顯示實現接口IMyInterface后,只能以下面方式訪問接口定義的方法:
IMyInterface a=new A(); a.func();
所以說:被顯示實現的接口方法只能通過接口實例訪問,而不能通過類實例直接訪問。