iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 12
0
Mobile Development

30 天從 Swift 學會 Objective-C系列 第 12

[12] 30 天從 Swift 學會 Objective-C:Objective-C 物件的封裝 Encapsulation

很多時候,我們有需要隱藏手法的時候,不論是阿嬤的秘密料理、魔術師的魔術、成功人士的成功方式,都有只有圈內人士才知道的秘密。而程式設計也是同樣道理的。

Photo by @1walter2 on Unsplash

Swift 的封裝

Swift 的封裝可以透過不少方式,我們目前先討論 protocol:

// Swift
/* Point.swift */
protocol Point: AnyObject {
    static func pointMake() -> Point
    func getx(_:Point) -> Int
    func gety(_:Point) -> Int
}

Swift 的 protocol 可以作為有前提的抽象類別,因此我們可以使用 let p: Point 的方式使用封裝。

接下來,我們圍繞這個 Point 來理解理解。

C 語言的封裝

C 語言的存在封裝的特性,透過在 Header 公開宣告,告訴程式碼的其他部分只有這些是公開的,其他則是不公開的。

// C
/* point.h */
struct point;
typedef struct point point;
point* pointMake(void);
int getx(point*);
int gety(point*);

Objective-C 的封裝

封裝或許在iOS 開發上可能用不太到,但是在 Library/Framework 的部分很值得討論。
首先請先看看下面這的 Public header。

// Objective-C
/* ITPoint.h */
#import <Foundation/Foundation.h>
@interface ITPoint : NSObject

+ (instancetype)make;
- (NSInteger)getx;
- (NSInteger)gety;
@end

這代表 Client 端可以呼叫到這三個函式。

而下面這個 header 檔沒有被納入 pubilc header 中

// Objective-C
/* ITPoint+internal.h */
#import "ITPoint.h"
@interface ITPoint ()
@property NSNumber * x;
@property NSNumber * y;
@end

也因為ITPoint.m 是圈內人士,可以知道所有的 header

// Objective-C
/* ITPoint.m */
#import "ITPoint.h"
#import "ITPoint+internal.h"

@implementation ITPoint
+ (instancetype) make {
    ITPoint* p =  [[self alloc] init];
    return p;
}
- (NSInteger)getx {
    return  [self.x intValue]; // self.x 屬於 internal
}
- (NSInteger)gety {
    return [self.y intValue];  // self.y 屬於 internal
}
@end

如此一來,NSNumber* xNSNumber* y 就會在不知不覺的情況下,進入到 Client 的程式碼內了!

簡單測驗

  1. 如果你要向程式新手說明什麼是封裝,你會如何解釋?
  2. [進階] 說明 C 語言的 struct point; 是什麼? 他的目的是什麼?
  3. [進階] Swift 的 Protocol 在有 associatetype 的時候是不能被作為變數型別的,那要如何才能使其可以呢? 例如 let h: Hashable

上一篇
[11] 30 天從 Swift 學會 Objective-C:Objective-C 物件的編寫
下一篇
[13] 30 天從 Swift 學會 Objective-C:Objective-C 物件的繼承 Inheritance, Protocol
系列文
30 天從 Swift 學會 Objective-C30

尚未有邦友留言

立即登入留言