Objective-C學習篇02—封裝,objective-c02封裝
物件導向的三大特性:封裝、繼承和多態
封裝目的就是將資料隱藏起來,外界只能通過這個類的方法(介面)才能訪問或者設定裡面的資料,不可以在外部直接修改或者訪問裡面的資料,通常使用方法來達到封裝一個類的目的,最終使這個類達到高內聚低耦合的目的.
耦合說的是一個軟體結構宏各個模組之間的相互關聯相互緊密的程度,模組之間的聯絡越精密,其耦合性也就越強,模組間耦合的高低取決於模組之間介面的複雜性,調用資訊的方式及傳遞的資訊.
內聚說的是單個模組內各個元素之間彼此結合的緊密程度,所謂高內聚就是一個軟體模組是由相關性很強的程式碼群組成,只負責一項任務.
一 Setter 和 getter方法的實現
設定器Setter的作用:為外界提供一個設定成員變數值的方法,說到底就是一種可以在外界調用,並為成員變數賦值的方法.
命名規範:
1. 一定是對象方法,以減號" - "開頭
2. 傳回值類型一定是 void
3. 方法名一定是: set+執行個體變數名去掉底線"_",且首字母大寫,比如:給_age 寫setter方法, setAge:
4. 一定要接收一個參數,不然如何進行賦值呢?參數類型一定要和執行個體變數的類型一致,參數名就是執行個體變數名去掉底線"_" 如: - (void)setAge:(NSInteger)age;
Setter方法的好處(1)不讓資料暴露在外,保證了資料的安全性;(2)對設定的資料進行過濾
Setter方法聲明:
// _age的setter方法- (void)setAge:(NSInteger)age;// _gender 的setter方法 - (NSInteger)gender;
Setter方法的實現:
// _age的setter方法- (void)setAge:(NSInteger)age { // 如果檢測到給年齡賦了值賦值,那麼直接返回 if (age < 0) { return; } // 將外界傳入的內容,賦值給執行個體變數 _age = age;}// _gender的setter方法- (void)setGender:(NSString *)gender { _gender = gender;}
訪問器 getter方法
getter方法的作用:為調用者返回對象內部的執行個體變數
命名規範:
1. 一定是對象方法,以"-"開頭
2. 一定有傳回值且傳回值類型和執行個體變數的類型一定要一致
3. 方法名: 不加get, 直接用 執行個體變數名去掉底線書寫 如: _age的getter方法是: age
4. 此方法不需要接收任何參數
getter方法的聲明:
// _age 的getter方法- (NSInteger)age;// _gender的getter方法- (NSString *)gender;
getter方法的實現:
// _age 的getter方法- (NSInteger)age { // 將執行個體變數返回就可以了 return _age;}// _gender的getter方法- (NSString *)gender { // 返回執行個體變數 return _gender;}
注意:在實際的開發過程中,如果內部的執行個體變數,比如學號之類的資料只允許外界讀取而不允許修改,那麼只需要提供get方法而不提供set方法.因此不一定setter和getter方法都會提供.
完整樣本:
建立一個Person類,對其執行個體變數實現setter和getter方法
Person.h
@interface Person : NSObject// 執行個體變數{ @public //執行個體變數可見度的修飾符,下面將會講到,暫時不用管 NSString *_name; //姓名
@protected NSInteger _age; //年齡
@private NSString *_gender; //性別}// _age的setter和getter方法- (void)setAge:(NSInteger)age;- (NSInteger)age;
// _gender的setter和getter方法- (void)setGender:(NSString *)gender;- (NSString *)gender;@end
Person.m
@implementation Person// _age的setter getter方法- (void)setAge:(NSInteger)age { if (age < 0) { return; } // 將外界傳入的內容,賦值給執行個體變數 _age = age;}- (NSInteger)age { // 將執行個體變數返回就可以了 return _age;}
// _gender的setter getter方法- (void)setGender:(NSString *)gender { _gender = gender;}- (NSString *)gender { // 返回執行個體變數 return _gender;}@end
二 執行個體變數的可見度
1.執行個體變數的可見度修飾符主要有3種:
可見度修飾符 類的內部 子類
@public 可以直接存取 可以直接存取
@protected 可以直接存取 可以直接存取
@private 可以直接存取 不可以直接存取
系統預設的執行個體變數可見度修飾符:@protected
執行個體變數的可見度的修飾符的作用範圍,從其所在的那一行起到大括弧結束,或者碰到下一個可見度修飾符結束;
@public
@public 修飾的變數雖然可以在類的外部直接存取,看起來很方便,但是破壞了類的封裝特性,所以不建議使用@public
@public 公用的,公開的,被它修飾的執行個體變數,不止能在類的內部直接存取,也能在類的外部直接存取方法;
內部訪問方式: 直接使用執行個體變數名 例如: _age
外部存取方式: 對象->執行個體變數名 例如: p->_age
Person *p = [[Person alloc] init];
// 調用_name的setter方法p->_name = @"張三"; //外部存取,使用->
// 調用_name的getter方法
NSLog(@"%@", p->_name);
@protected
@protected 受保護的,不允許在類的外部直接存取,但是可以在類的內部和子類的內部直接存取,是系統預設的執行個體變數可見度.
// 內部訪問: 直接使用執行個體變數名
// 外部存取: 賦值需要通過設定器setter進行訪問,取值通過訪問器getter進行訪問
//調用_age的setter方法: [p setAge:-10]; //調用_age的getter方法 NSInteger age = [p age];
@private
@private 私人的,外部不能直接存取,內部可以直接存取,在子類中不可以直接存取,但是可以通過方法進行訪問
內部訪問: 通過接使用執行個體變數名
類的外部: 通過設定器和訪問器訪問
// 調用_gender的setter方法 [p setGender:@"男"]; // 調用_gender的getter方法 NSLog(@"%@", [p gender]);
練習: 定義一個Student類型,執行個體變數使用三種可見度,修飾其三個執行個體變數.使用protect, private修飾的變數寫setter和getter方法
Student.h檔案中聲明:
@interface Student : NSObject{ @public NSString *_name;
@protected NSInteger _number;
@private CGFloat _score;}// _number 的setter getter方法- (void)setNumber:(NSInteger)number;- (NSInteger)number;// _score 的setter getter方法- (void)setScore:(CGFloat)score;- (CGFloat)score;@end
Student.m檔案中實現:
@implementation Student // _number 的setter方法- (void)setNumber:(NSInteger)number { _number = number;}// _number 的getter方法- (NSInteger)number { return _number;}// _score 的setter方法- (void)setScore:(CGFloat)score { _score = score;}//_score 的getter方法- (CGFloat)score { return _score;}@end
回到main中調用各執行個體變數的setter 和getter方法:
// 建立一個Student對象stu: Student *stu = [[Student alloc] init];
// 被@protected修飾的執行個體變數 _number // 調用_number的setter方法 [stu setNumber:123456];
// 調用_number的getter方法 NSLog(@"%ld", [stu number]);
// 被@private修飾的 _score // 調用 _score 的setter方法 [stu setScore:80.0];
// _score 的getter方法 NSLog(@"%.2f", [stu score]);
點文法
如果一個執行個體變數對它實現了setter和getter語方法,就可以使用點文法了.因此,使用點文法的前提是對該執行個體變數使用了setter和getter方法
點文法只是setter和getter方法的一種快捷調用
stu.number = 12315; // 就相當於 [stu setNumber:12315]; NSLog(@"%ld", stu.number); // 相當於 [stu number];
點文法使用總結: 如果後面有賦值運算子(=),此時此時相當於這個執行個體變數的setter方法;後面沒有賦值運算子,此時相當於調用這個執行個體變數的getter方法