[objective-c] Interface & Protocol & Categories

來源:互聯網
上載者:User
 1  Interface(介面約定)

       Interface理解為介面概念,於JAVA\C#中的介面有所不同的是Obj-C中的介面應該理解為一種非正式協議,Obj-C中的Interface只是表明應該會處理其中聲明的訊息(方法),但是不是必須處理。

     

     表明Sample Interface中,約定了應該會處理HelloWorld訊息,但是Sample.m中我們可以不去實現對HelloWorld的處理,這樣編譯器會給出警告但是編譯可以通過,但是在程式中向Sample發送該訊息會引發異常。

2  Protocol(正式協議)

      Protocol(正式協議)看上去更正規一些,語義上更強烈一些:要求採用該協議的類,"必須"實現協議中約定的方法。但是比較娛樂的是,即使是號稱正式協議,編譯器在編譯時間,遇到不守規矩的情況,仍然只是給出警告。你會覺得Protocol跟Interface比起來,都是類似的概念,Protocol設計純屬多餘。其實不然,Protocol存在的一個重要意義在於:

Protocol(正式協議)可以將業務中的方法定義剝離出來,形成一個單獨的檔案,這跟傳統OO中的提取介面是不謀而合的。如果遇到二個系統需要交換資料,可以制定一套雙方都遵守的Protocol,然後這二個系統中都把這個協議檔案添加到項目中,實現它即可。

    這一功能,非正式協議(@interface)是做不到的。因為在Obj-C中是不允許多繼承的,雙方系統可能都需要繼承某一個類以實現某些功能,這時候只能實現一個協議(Protocol)。 此外,Obj-C 2.0中對協議還做了一些擴充,允許把協議中的方法標識為“必須實現(@required)”和“可選實現(@optional)”二類,如果協議中的方法被標識為@optional,即使採用該協議的類不實現這些方法,編譯器也不會給出警告。這樣介面約定的很多作用就可以由協議來實現,不過協議中不能含有資料(但是介面約定中可以有資料成員)。

     NSObject是一個Interface也是一個Protocol,而Interface NSObject實現了Protocol NSObject,在Obj-c的OO世界中,身為萬物之祖的NSObject其實也就一個"正式協議”,所以從NSObject派生出的所有類,都只是在遵守一個或多個協議而已。

3 Categories (類型分類,非正式協議)

      非正式協議並沒有設計為正式協議的寬鬆版本,而是設計為Class Categories(類型分類)。Categories是Objective-C裡面最常用到的功能之一。大體上說,Categories可以讓我們給已經存在的類增加方法,而不需要增加一個子類。而且不需要知道它內部具體的實現。如果我們想增加某個framework內建的類的方法,這非常有效。如果我們想在我們程式工程的NSString能夠增加一個方法,我們就可以使用Categories,不需要自己實現一個NSString的子類。比如,我們想在NSString裡面增加一個方法來判斷它是否是一個URL,那我們就可以這麼做:

1) 在categoriesTest.h標頭檔中:

   1:  @interface NSString (URLDetecter)
   2:  - (BOOL) isURL;
   3:  @end

     這跟類的定義非常類似。區別就是category沒有父類,而且在括弧裡面要有category的名字。名字可以隨便取,但是習慣叫法會讓人比較明白category裡面有些什麼功能的方法。這裡是具體的實現。但是要注意,這本身並不是一個判斷URL很好的實現。我們主要是為了整體的瞭解category的概念。

2) 在categoriesTest.m中給出實現

   1:  #import "categoriesTest.h"
   2:  @implementation NSString (URLDetecter)
   3:  - (BOOL) isURL{  
   4:    if ( [self hasPrefix:@"http://"] )    
   5:        return YES;
   6:    else 
   7:       return NO;  
   8:  }@end

3) 在main.m中使用NSString的時候如下:

   1:  NSString* string1 = @"http://www.CocoaDev.cn/";
   2:  NSString* string2 = @"Pixar";
   3:  if ([string1 isURL])  NSLog(@"string1 is a URL");
   4:  if([string2 isURL])  NSLog(@"string2 is a URL");

4)  如果在main.m沒有import標頭檔categoriesTest.h,會有如下警告

     warning: 'NSString' may not respond to '-isURL' 

     warning: (Messages without a matching method signature

     warning: will be assumed to return 'id' and accept

     warning: '...' as arguments.

     編譯器認為NSString不會對訊息isURL作出回應。

     此時運行得到的結果如下:

    

5)  如果在main.m中import標頭檔categoriesTest.h

     運行結果如下:

    

     跟子類不一樣,category不能增加成員變數。我們還可以用category來重寫類原先的存在的方法,但是這需要非常非常小心。記住,當我們通過category來修改一個類的時候,它對應用程式裡的這個類所有對象都起作用。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.