2013年3月31日 星期日

<心得> Introduce class interface in Grasshopper C#

目標 : 介紹基本介面關係概念以及簡單介面範例。

參考文獻 :

http://www.cnblogs.com/oomusou/archive/2007/05/07/738311.html


////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//此處描述 :

interface用在當一個物件須和其他物件共同合作時,為了確保其他物件有使者想要的method,所以定下interface,interface就是多個class中裡面有許多相同的method,所以抽取出來作為介面讓大家共同使用,可以在各自的介面中使用相同method名子卻可以有不同的功能。

而abstract class是用在整個繼承體系的最上層,用來定義出整個繼承體系該有哪些method,子類別可以對這些method加以override或維持和abstract class相同的功能,使用繼承技術時,我們會將所有method由abstract class去宣告,然後由各子類別去override,若不得已某些class有自己的特殊method,則由該class自行宣告。關於inheritance請參考Introduce class inheritance in Grasshopper C#

在OO主要有兩種技術:繼承(Inheritance)和組合(Composition),而abstract class就是用在使用繼承技術時,而interface則是用在使用組合技術時。

一旦使用組合時時,就牽涉到一個問題,你如何確保被你組合的物件有某個method當你使用繼承時,因為所有的method都會被繼承,這不是問題,但組合就不一樣了,所以你必須建立一個interface,強迫要被你組合的物件,需實做這個interface,這樣當你要使用該物件時,才能確保有某個method可以呼叫。

由Fig01 我們可以看出有兩個基本的父層(Base),然後子層Parent(Parent繼承Base)和子層child(child繼承Parent)分別繼承上層的關係,只有在Parent中創建method 的方法叫做ApplyEdiable然後子層Child 繼承ApplyEdiable的method

由Fig02 因為ParentA 和 ParentB 有共同的method 叫做ApplyEdiable,所以我們創建BaseC讓裡面擁有名為ApplyEdiable的method,再創建一個interface名為IBaseCAction來真正實踐ApplyEdiable的內部功能,這樣在ChildA、ChildB就可以共同使用ApplyEdiable的method


Fig 01. inheritance 繼承關係圖


Fig 02.interface 介面關係圖


////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//此處示範基本interface創建方式

//使用關鍵字interface
//介面名為
IcircleA
//在介面中只能宣告方法名子與參數,真正實作部分必須在各類別使用中實現
  public interface IcircleA{
    Circle createCircle(Point3d center, double rad);
  }

//類型shapeA  使用介面 IcircleA
  public class shapeA : IcircleA{

    public Circle createCircle(Point3d center, double rad){
      Circle mycircle = new Circle(center, rad);
      return mycircle;
    }

  }

//創建類型shapeA  
//並呼叫介面方法且指定參數

  shapeA mytest = new shapeA();
    A = mytest.createCircle(new Point3d(0, 0, 0), 10.0);

輸出圖像:
使用interface所創建的圓

//如果遇上多個interface 中有著相同的名稱method,必須創建原始介面,才能呼叫方法
//參考文章 : http://msdn.microsoft.com/zh-tw/library/ms173157(v=vs.80).aspx

//請注意interface IcircleA and IcircleB擁有相同的mehod 名稱為 createCircle


  public interface IcircleA{
    Circle createCircle(Point3d center, double rad);
  }

  public interface IcircleB{
    Circle createCircle(Point3d center, double rad);
  }


//class shapeA實行介面 IcircleA,IcircleB兩個介面
//注意 Circle IcircleA.createCircle 的Circle 之前不能加上public

 public class shapeA : IcircleA,IcircleB{

    Circle IcircleA.createCircle(Point3d center, double rad){
      Circle mycircle = new Circle(center, rad);
      return mycircle;
    }

    Circle IcircleB.createCircle(Point3d center, double rad){
      Circle mycircle = new Circle(center, rad / 2);
      return mycircle;
    }

  }


//instance shapeA 

    shapeA mytest = new shapeA();

//呼叫createCircle 藉由已經存在的mytest物件中執行名為IcircleA的介面
//因為使用者有兩個相同的method 所以必須明確的告知compiler 哪個才是你想執行的介面方法
//所以呼叫到介面的那層 

    shapeA mytest = new shapeA();

    IcircleA circleA = (IcircleA) mytest;
    A = circleA.createCircle(new Point3d(0, 0, 0), 10.0);

    IcircleB circleB = (IcircleB) mytest;
    B = circleB.createCircle(new Point3d(0, 0, 0), 10.0);



輸出圖像:



使用相同名稱的method所創建的圓



////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//使用時機 


>>何時使用main function
若公司不到5個人,老闆只要將要做的事情規定好(function),然後指定某個人去做某件事情即可(main function),這種『中央集權』的方式就是『程序導向』,在小公司是很有效率的。

>>何時使用OOP
若是上千人的公司,老闆不可能同時指揮所有人,所以有經理,科長等管理階層出現,老闆只要管好經理,經理只要盯住科長,科長再分配事情給小職員做,這種『分層負責』,每個人將自己分內做好的方式,就是『物件導向』,大公司一定得用這種方式才能管理。
軟體開發也是一樣,小程式用『程序導向』方式寫就很方便,但大程式則必須用『物件導向』方式才好管理,軟體開發和企業管理是相通的。
>>何時要用 interface 而不要使用父類別
盡量用 interface, 盡量不要用父類別, 如果例子簡化成 '動物一定有眼睛, 需要由各子類別去實作', 而 '動物' class 裡也沒別的定義, 那麼就是使用 interface 的標準狀況, 完全不必考慮是否要使用 abstract class

>>何時要用父類別而不要使用 interface
如果父類別有寫一些 method, property ,你想讓子類別能繼承後就順便有它們,就用父類別, 至於父類別要宣告成 class or abstract class, 看父類別想不想被 new

在 C#, VB.NET 語言裡, 一個類別只能繼承一個 class, 可以實作多個 interface, 所以換個角度來看, 寫程式時不要這麼 '敗家' , 隨便地就將維一一個繼承的機會就用掉了  


////////////////////////////////////////////////////////////////////////////////////////////////////////////////

沒有留言:

張貼留言