物件導向的三大概念中,多型屬於最難懂的一個觀念。以生活中的例子來解釋,假如在一個班級中,老師命令學生搬桌子。不論是命令學生甲或是學生乙,老師同樣都是說:把桌子搬走。但學生甲跟學生乙搬桌子的方法會不會都相同?學生甲也許是整張桌子抬起來,學生乙可能比較懶,桌子是拖著走的。

軟體中會不會遇到這樣的情況?在一個看圖軟體中,開啟圖檔是再平常不過的一件事。但圖檔的格式有千百種,每一種格式的開啟方式都不一樣,這個時候程式該怎麼寫呢?或許有人會用以下的方法:

        if(filepath的副檔名為jpg)
                使用開啟jpg的函式;
         if(filepath的副檔名為png)
                 使用開啟png的函式;
.................

如果支援的格式愈多,條件判斷式勢必會增加,在這樣的情況下,程式會變得愈來愈難維護。比較好的方法應該是以下這種方式:

openfile(filepath);

把開啟檔案的功能獨立為一個功能,讓程式碼更為簡潔,但函式裡面的方法又該如何實作呢?這個時候就可以使用多型的方法。

以下的程式是一個簡單的程式:
 class shade
 {
          private int x,y;
          public shade(int x, int y)
          {
                   this.x = x;
                   this.y = y;
          }
  
          public virtual void print()
          {
                   Console.WriteLine("這是形狀,座標為({0},{0})",x,y);
          }
 }

 class triangle:shade
 {
          private int lengthX, lengthY, lengthZ;
          public triangle(int x,int y,int z):base(20,10)
          {
                   this.lengthX = x;
                   this.lengthY = y;
                   this.lengthZ = z;
          }
          public override void print()
          {
                   Console.WriteLine("這是三角形,邊長分別為:{0}、{0}、{0}"
                                                        ,lengthX,lengthY,lengthZ);
          }
}

 class supTriangle:triangle
 {
          public supTriangle(int x,int y,int z):base(x,y,z)
          {
          }
          public override void print()
          {
                   Console.WriteLine("這是超級三角形");
          }
 }

在這裡先實作一個shade類別,之後再讓其它的類別繼承它。而所有的類別都會實作一個print函式。這個函式的主要用意就是顯示類別本身的資訊。接下來實作main函式,讓整個程式可以執行:

 class Class1
 {
          /// <summary>
          /// 應用程式的主進入點。
          /// </summary>
          [STAThread]
          static void Main(string[] args)
          {
                   //
                   // TODO: 在此加入啟動應用程式的程式碼
                   //
                   triangle a = new triangle(3,3,9);
                   supTriangle b = new supTriangle(3,3,12);

                   printInfo(a);
                   printInfo(b);
          }

          static void printInfo(shade printer)
          {
                   printer.print();
          }
 }

雖然a跟b是不同的類別,但是同樣都可以丟進printInfo函式裡,函式所接受的參數為父類別shade。但是在執行類別裡的print方法時,會自動尋找適合的print。雖然是父類別shade,但supTriangle以及triangle的print方法實際上都還是存在著,所以並不會執行shade的print方法。

從多型的概念中,可以讓程式的寫作能以抽象的方法去思考。但多型的代價其實是很高的,所以在使用時要選對時機。

註:以上的程式碼是使用C#語言。


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 卑微研究生 的頭像
    卑微研究生

    卑微研究生的部落格

    卑微研究生 發表在 痞客邦 留言(1) 人氣()