【C#】OOP之多態那點事

來源:互聯網
上載者:User

標籤:style   blog   http   color   java   使用   os   io   

前言: 對菜鳥開發人員的忠告:花一萬個小時練習 Coding,不要浪費一萬小時無謂地 Debugging(也就說看代碼)

 

                       

看上面的UML圖,我們建立一個抽象的Instrument類,類中有一個抽象方法paly,然後所有的子類都繼承這個類並實現paly方法。(若不懂繼承,請參照另一篇:OOP之繼承那點事)

我們來看一下類的實現:

    public abstract class Instrument    {        public abstract void Play();    }    public class Guitor : Instrument    {        public override void Play()        {            Console.WriteLine(string.Format("Play {0}", this.GetType().Name));        }    }    public class Paino : Instrument    {        public override void Play()        {            Console.WriteLine(string.Format("Play {0}", this.GetType().Name));        }    }    public class Violin : Instrument    {        public override void Play()        {            Console.WriteLine(string.Format("Play {0}", this.GetType().Name));        }    }
View Code

在每個子類方法裡,我們直接出去字串。

  class Program    {        static void Main(string[] args)        {            Guitor g = new Guitor();            g.Play();            Paino p = new Paino();            p.Play();            Violin v = new Violin();            v.Play();            Console.ReadLine();        }    }
View Code

在Main方法裡,我們建立了三個對象,然後分別輸出。 這個說在我們還沒開始多態之前的寫法,好麻煩有木有(木有?蹲角落寫100個樂器的paly).那什麼是多態呢?

什麼是多態:一種形態的多種表現形式(好抽象...)

THINK IN JAVA上寫到:多態是消除類型之間的耦合關係(還是很抽象)

  直接看例子:

    class Program    {        static void Main(string[] args)        {            PlayInstrument(new Guitor());            PlayInstrument(new Paino());            PlayInstrument(new Violin());            Console.ReadLine();        }        public static void PlayInstrument(Instrument instrument)        {            instrument.Play();        }    }
View Code

  這樣的輸出是和上面的例子是一樣的,我們改變了什麼,我們提供了一個方法,把3個子類的引用放了進去,呀,為什麼PlayInstrument的形參是Instrument的對象,這就是多態的關鍵之處,

我總結了一句話:子類的引用(new Guitor())指向父類的對象(Instrument instrument) ;

  

       static void Main(string[] args)        {            Instrument instrument = new Guitor();            instrument = new Paino();            instrument = new Violin();            Console.ReadLine();        }
View Code

   這個好神奇有木有,我初學時間也覺得,這個好神奇,這個這麼玩的,讓我來帶領大家進入神秘的多態空間。

  

  

  向上轉型

     

       static void Main(string[] args)        {            Guitor gutior = new Guitor();            Instrument instrument = gutior;            Console.ReadLine();        }
View Code

 

向上轉型,就說把子類的類型轉成父類的,這樣是安全的,看上面的例子,如果在VS IDE工具中查看,是沒有編譯報錯的,這時為什麼呢?我們來看張圖。

這個圓我們把他當作堆(heap)來看,(這沒有畫棧,因為指向討論向上轉型的安全).我們來看一下Guitor裡麵包含了Instrument的所有的東西(除了構造,如果說你點不出來私人化的東西,你可以嘗試用反射,它的確存在) ,這樣我們把大塊變成小塊是不是很安全呢,因為我大塊擁有小塊裡面所有的東西,所以說向上轉型是安全的。

  

註:相反來說,向下轉型是危險的,因為小塊變成大塊,你不可以控制裡面的東西。(協變和逆變概念也差不多,我比較喜歡叫成和諧的變->安全,逆天的變->危險)

這樣的話,我們把大塊轉換成小塊(Instrument instrument=new Guitor()),我們只能調用到小塊的東西了(所以我們在設計的時候,一般會用介面去限定)

  

  介面其實是應該單獨拉出來談的,但是由於介面基本概念不多,只是在我們OO設計中,介面用處很大,這裡屬於設計範圍,在多態中,用介面做父類和用類寫法一樣的,可以去試試。

  

  總結一下:

  1.向上轉型以後,雖然引用還是原本的子類,但是只能用父類的方法了(想想大塊變小塊)

  2.父類方法被子類重寫了(virtual,override)以後,向上轉型以後,調用相同的方法還是大塊的(因為小塊的被重寫了,這樣說感覺很牽強,因為如果我們在子類中用base關鍵字還是能調用父類的同名方法,至於這塊的記憶體的調用,我一直沒找到相關資料,如果有人知道,請分享一下,萬分感謝)。

  3.介面和抽象類別(類)在使用多態的上面是同一個形式

  

 

  感覺這邊寫的不好...望大家補充和指出不足,謝謝了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.