c#基礎語言編程-多態

語言中的多態性是爲了使程序有擴展性,爲實現多態性,在程序中體現爲接口、抽象類、父類、具體類。
接口就是一種規範,解決了多重繼承的問題,類似一種規範,告訴我要做什麼,具有什麼能力,在接口中定義寫行爲屬性。

接口的特性

  1. 接口類類似抽象類,不能實例化接口;接口中的方法都是抽象方法,繼承於此接口的非抽象類必須實現接口中所有成員。
  2. 接口只能包含方法(屬性、事件、索引器最終都是方法),不能有字段、常量、構造函數和析構函數、靜態變量,但是可以有委託和事件。
  3. 接口中成員不許有訪問修飾符,默認爲public,手動添加會編譯出錯。 接口中成員只有定義,沒有任何實現,像抽象類一樣
  4. 實現接口的類,直接實現接口中的方法,不用寫override。
  5. 當顯示該接口的成員時,實例成員不能通過類實例訪問(不提倡用類實例訪問,這樣就無法體現多態性),只能通過接口實例訪問,顯示實現默認是private。當隱示實現接口成員,兩者實例都能訪問,但是要將成員表示爲public。
    比如:
   public class Person : IFace1, IFace2
    {
        public void Fly()
        {
            Console.WriteLine("實現了IFace1中的Fly方法。");
        }

        //顯示實現接口的訪問修飾符默認是沒有的,類中成員沒有寫訪問修飾符這默認就是private 
        //顯示實現接口是私有的所以必須通過接口名才能訪問的到。
        void IFace2.Fly()
        {
            Console.WriteLine("實現了IFace2中的Fly方法。");
        }
    }

    public interface IFace1
    {
        void Fly();
    }
    public interface IFace2
    {
        void Fly();
    }
Person p = new Person();
 p.Fly();//face1中的Fly()face2中顯示實現,爲private,通過new Person 無法獲取到。

 IFace1 f1 = new Person();
  f1.Fly();//face1中的Fly()

 IFace2 f2 = new Person();
 f2.Fly();//face2中的Fly()

virtual和override的應用
virtual是虛函數的關鍵詞,override是重寫的關鍵詞。有virtual關鍵詞,意味允許繼承者可以用override重寫。如果不用override,則不是重寫。
例如:

 class Person 
    {
        public virtual void Introduce()
        {
             Console.WriteLine("我是來自地球");
        }
    }

    class Chinese : Person
    {
        public override void Introduce()
        {
            Console.WriteLine("我的戶口,身份證號碼");
        }
    }
 class American : Person
    {
    //此處沒有加override,所以在後續代碼中無法調用此方法。
        public  void Introduce()
        {
            Console.WriteLine("社會保險號:00000");
        }
    }

Person p1 = new Chinese();
p1.Introduce();
Person p2 = new American();
p2.Introduce();

顯示的結果爲:我的戶口,身份證號碼。我是來自地球

當一個抽象類實現接口的時候,如果不想把接口成員實現,可以把成員實現爲abstract。
爲什麼不能指定接口中方法的修飾符?
接口中的方法用來定義對象之間通信的契約,指定接口中的方法爲私有或保護沒有意義。它們默認爲公有方法。

抽象類

抽象類是包含抽象方法的類。那麼什麼又是抽象方法呢?抽象方法是沒有方法內容的,只有一個方法名和參數列表的方法。並以;結尾。爲了標註他的與衆不同,在他的返回類型前加abstract。並在class前加abstract。
簡言之,由abstract修飾的方法和類就是抽象的方法和類。

 //抽象狀態類State,定義一個接口以封裝與Context的一個特定狀態相關的行爲  
    abstract class State  
    {  
        public abstract void Handle(Context context);  
    }  

    //ConcreteState類,具體狀態,每一個子類實現一個與Context的一個狀態相關的行爲  
    class ConcreteStateA : State  
    {  
        public override void Handle(Context context)  
        {  
            //設置ConcreteStateA的下一個狀態是ConcreteStateB  
            context.State = new ConcreteStateB();  
        }  
    }  

    class ConcreteStateB : State  
    {  
        public override void Handle(Context context)  
        {  
            //設置ConcreteStateB的下一個狀態是ConcreteStateA  
            context.State = new ConcreteStateA();  
        }  

    }  

抽象類不能實例化,必須通過繼承由派生類實現其抽象方法,因此對抽象類不能使用new關鍵字,也不能被密封。如果派生類沒有實現所有的抽象方法,則該派生類也必須聲明爲抽象類。另外,實現抽象方法由override方法來實現。
接口與抽象類的相同點:
1、不能實例化;
2、包含未實現的方法聲明;
3、派生類必須實現未實現的方法,抽象類是抽象方法,接口則是所有成員(不僅是方法包括其他成員);
接口和抽象類的區別
1.類是對對象的抽象,可以把抽象類理解爲把類當作對象,抽象成的類叫做抽象類.而接口只是一個行爲的規範或規定
2.接口基本上不具備繼承的任何具體特點,它僅僅承諾了能夠調用的方法;
3.一個類一次可以實現若干個接口,但是隻能擴展一個父類
4.接口可以用於支持回調,而繼承並不具備這個特點.
5.抽象類不能被密封。
6.抽象類實現的具體方法默認爲虛的,但實現接口的類中的接口方法卻默認爲非虛的,當然您也可以聲明爲虛的.
7.(接口)與非抽象類類似,抽象類也必須爲在該類的基類列表中列出的接口的所有成員提供它自己的實現。但是,允許抽象類將接口方法映射到抽象方法上。
8.抽象類實現了oop中的一個原則,把可變的與不可變的分離。抽象類和接口就是定義爲不可變的,而把可變的座位子類去實現。
9.好的接口定義應該是具有專一功能性的,而不是多功能的,否則造成接口污染。如果一個類只是實現了這個接口的中一個功能,而不得不去實現接口中的其他方法,就叫接口污染。
10.儘量避免使用繼承來實現組建功能,而是使用黑箱複用,即對象組合。因爲繼承的層次增多,造成最直接的後果就是當你調用這個類羣中某一類,就必須把他們全部加載到棧中!後果可想而知.(結合堆棧原理理解)。同時,有心的朋友可以留意到微軟在構建一個類時,很多時候用到了對象組合的方法。比如asp.net中,Page類,有Server Request等屬性,但其實他們都是某個類的對象。使用Page類的這個對象來調用另外的類的方法和屬性,這個是非常基本的一個設計原則。
11.如果抽象類實現接口,則可以把接口中方法映射到抽象類中作爲抽象方法而不必實現,而在抽象類的子類中實現接口中方法.
12. 接口定義方法,不能實現,而抽象類可以實現部分方法。
13.接口中基本數據類型爲static 而抽類象不是的。
抽象類的功能要遠超過接口,但是,定義抽象類的代價高。因爲高級語言來說(從實際設計上來說也是)每個類只能繼承一個類。在這個類中,你必須繼承或編寫出其所有子類的
所有共性。雖然接口在功能上會弱化許多,但是它只是針對一個動作的描述。而且你可以在一個類中同時實現多個接口。在設計階段會降低難度的。
如何理解抽象類和接口
1.飛機會飛,鳥會飛,他們都繼承了同一個接口“飛”;但是F22屬於飛機抽象類,鴿子屬於鳥抽象類。
2.就像鐵門木門都是門(抽象類),你想要個門我給不了(不能實例化),但我可以給你個具體的鐵門或木門(多態);而且只能是門,你不能說它是窗(單繼承);一個門可以有鎖(接口)也可以有門鈴(多實現)。門(抽象類)定義了你是什麼,接口(鎖)規定了你能做什麼(一個接口最好只能做一件事,你不能要求鎖也能發出聲音(接口污染))。
什麼時候用接口實現多態?
答:當多個類型不能抽象出合理的父類時,但是又要對一些方法進行多態,此時可以考慮用接口。講公共的方法抽象到一個接口中。
程序設計的原則(自己聽課的結果)

  1. 接口》抽象類》父類》具體類(在定義方法參數、。返回值、聲明變量的時候能使用抽象就不要使用具體參數。
  2. 能使用接口就不要使用抽象類,能使用抽象類就不要用類,能用父類就不要用子類。
  3. 避免使用”體積龐大的接口“”多功能接口“會造成接口污染。
  4. 單一職責、開放封閉、里氏替換、接口隔離、依賴接口
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章