2012年10月24日 星期三

Abstract Class in Objective-C

Abstract class 在物件導向語言中是個十分重要的工具
當 programmer 看到 abstract class 時,心中應該浮現出以下含義:
  1. 此 class 沒有實作完成,至少有一個 member method 需要繼承的 subclass 實作
  2. 強制 subclass 實作某些 methods
  3. 此 class 無法被 instantiate,它是用來被繼承的
Abstract class 在許多物件導向語言中都有關鍵字支援,例如: Java, C#
而 C++ 則是利用 pure virtual functions 來表達此 class 是一個 abstract class
然而 Objective-C 並未提供關鍵字或者語法來宣告出一個 abstract class [2]

不過其實可以利用一些語法來讓 Objective-C 模擬一個 abstract class
利用 NSException 來防止 programmer instantiate abstract class 和 call abstract method:

  • 禁止 instantiate abstract class
在 abstract class 中的 init 與其他 instantiation methods 中,寫入以下程式碼:


- (id)init
{
  if ([self class] == [FastEnumerable class]) {
    @throw [NSException exceptionWithName:NSInternalInconsistencyException
      reason:@"Attempting to instantiate AbstractClass directly." userInfo:nil];
  }

  self = [super init];
  if (self) {
    // Initialization code here.
  }

  return self;
}


  • 禁止 call abstract method
在 abstract class 中的 abstractMethod,寫入以下程式碼:


- (void)abstractMethod
{
  @throw [NSException exceptionWithName:NSInternalInconsistencyException
        reason:[NSString stringWithFormat:@"You must override %@ in a subclass.",
        NSStringFromSelector(_cmd)]
        userInfo:nil];
}

    利用這樣的方式,便可以模擬出 abstract class 了
    不過這種模擬方式並非在 compile time 發生錯誤,而是在 run time

    若想要把此變成 Xcode 的 templates,這邊有提供檔案:


    解壓縮後把 MAC 資料夾下的 Objective-C abstract class.xctemplate 放至
    /Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/File Templates
    把 iOS 資料夾下的 Objective-C abstract class.xctemplate 放至
    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/File Templates

    註:上述的路徑跟 Xcode 版本有關,這邊所指路徑適用於 Xcode 4

    Reference:
    [1] ABSTRACT CLASSES AND OBJECTIVE-C, XCODEIT
    [2] The Objective-C Programming Language, Apple