一、封裝 封裝:隱藏對象的屬性和實現細節,僅對外公開介面,控製程序中屬性的讀和修改的訪問級別。 person.h: person.m: 優點: 1. 隱藏內部實現細節,設置訪問許可權,提高了數據的安全性。 2. 任何出入的數據都要流經介面,通過重寫set方法可以起到過濾數據的作用。 二、繼承 繼承:指 ...
一、封裝
封裝:隱藏對象的屬性和實現細節,僅對外公開介面,控製程序中屬性的讀和修改的訪問級別。
person.h:
1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObject 4 /** 年齡 */ 5 @property (nonatomic, assign) int age; 6 7 @end
person.m:
1 #import "Person.h" 2 3 @implementation Person 4 5 #pragma mark - 重寫set方法 6 - (void)setAge:(int)age { 7 if (age < 0) { 8 NSLog(@"年齡不能為負數"); 9 return; 10 } else { 11 _age = age; 12 return; 13 } 14 } 15 16 @end
優點:
1. 隱藏內部實現細節,設置訪問許可權,提高了數據的安全性。
2. 任何出入的數據都要流經介面,通過重寫set方法可以起到過濾數據的作用。
二、繼承
繼承:指一個對象直接使用另一對象的屬性和方法。
Person.h:
1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObject 4 /** 年齡 */ 5 @property (nonatomic, assign) int age; 6 /** 吃方法 */ 7 - (void)eat; 8 9 @end
Person.m:
1 #import "Person.h" 2 3 @implementation Person 4 5 #pragma mark - 重寫set方法 6 - (void)setAge:(int)age { 7 if (age < 0) { 8 NSLog(@"年齡不能為負數"); 9 return; 10 } else { 11 _age = age; 12 return; 13 } 14 } 15 16 #pragma mark - 吃方法實現 17 - (void)eat { 18 NSLog(@"Person 吃飯"); 19 } 20 21 @end
GoodPerson.h:
1 #import "Person.h" 2 3 // 繼承父類Person 4 @interface GoodPerson : Person 5 /** 姓名 */ 6 @property (nonatomic, strong) NSString *name; 7 8 @end
GoodPerson.m:
1 #import "GoodPerson.h" 2 3 @implementation GoodPerson 4 5 - (void)eat { 6 NSLog(@"GoodPerson 吃飯"); 7 } 8 9 @end
main.m:
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 #import "GoodPerson.h" 4 5 6 int main(int argc, const char * argv[]) { 7 /** 人 */ 8 Person *p = [[Person alloc] init]; 9 p.age = 20; 10 [p eat]; 11 12 /** 好人 */ 13 GoodPerson *goodP = [[GoodPerson alloc] init]; 14 goodP.age = 30; 15 [goodP eat]; 16 17 // 好人姓名 18 goodP.name = @"Lkun"; 19 NSLog(@"好人name = %@", goodP.name); 20 21 22 return 0; 23 }
編譯運行結果:
2016-08-18 17:53:37.484 01-discription[634:455001] Person 吃飯 2016-08-18 17:53:37.485 01-discription[634:455001] GoodPerson 吃飯 2016-08-18 17:53:37.485 01-discription[634:455001] 好人name = Lkun Program ended with exit code: 0
註解:
1. 大部分類都繼承自NSObject父類,所以也都繼承了該類的屬性和方法。
2. GoodPerson雖繼承了父類Person的屬性age和方法eat,但卻有其獨特的方法name,且重寫了父類的方法eat。
3. 當子類對象收到方法消息時則逐層查找,找到即執行。如setName方法在GoodPerson父類就可以找到,而setAge類得在Person父類才能找到
優點:抽取重覆代碼、建立聯繫
缺點:耦合性強
繼承:狗是動物,所以狗繼承動物類
組合:學生擁有狗,所以把狗作為學生類的一個屬性
三、多態
多態:父類指針指向子類對象,父類類型參數可以接收子類類型參數的傳入
Person.h:
1 #import <Foundation/Foundation.h> 2 #import "Animal.h" 3 4 @interface Person : NSObject 5 // 喂食動物的方法 6 - (void)feedAnimal:(Animal *)animal; 7 8 @end
Person.m:
1 #import "Person.h" 2 3 @implementation Person 4 5 - (void)feedAnimal:(Animal *)animal { 6 [animal eat]; 7 } 8 9 @end
Animal.h:
1 #import <Foundation/Foundation.h> 2 3 @interface Animal : NSObject 4 /** 吃方法 */ 5 - (void)eat; 6 7 @end
Animal.m:
1 #import "Animal.h" 2 3 @implementation Animal 4 5 - (void)eat { 6 NSLog(@"Animal eat"); 7 } 8 9 @end
Cat.h:
1 #import "Animal.h" 2 3 @interface Cat : Animal 4 5 @end
Cat.m:
1 #import "Cat.h" 2 3 @implementation Cat 4 #pragma mark - 重寫父類的吃方法 5 - (void)eat { 6 NSLog(@"Cat eat"); 7 } 8 9 @end
Dog.h:
1 #import "Animal.h" 2 3 @interface Dog : Animal 4 5 @end
Dog.m:
1 #import "Dog.h" 2 3 @implementation Dog 4 #pragma mark - 重寫父類吃方法 5 - (void)eat { 6 NSLog(@"Dog eat"); 7 } 8 9 @end
main.m:
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 #import "Animal.h" 4 #import "Cat.h" 5 #import "Dog.h" 6 7 8 int main(int argc, const char * argv[]) { 9 /** 人 */ 10 Person *p = [[Person alloc] init]; 11 12 /** 動物 */ 13 Animal *a = [[Animal alloc] init]; 14 15 /** 貓 */ 16 Cat *c = [[Cat alloc] init]; 17 18 // 父類指針指向Dog實例對象 19 Animal *d = [[Dog alloc] init]; 20 21 22 // 動態檢測真正對象是Dog 23 [d eat]; 24 25 // 父類指針類型的參數也可以接收子類指針類型的參數 26 [p feedAnimal:a]; 27 [p feedAnimal:c]; 28 29 30 return 0; 31 }
編譯運行結果:
2016-08-18 19:42:59.467 01-discription[759:669325] Dog eat 2016-08-18 19:42:59.468 01-discription[759:669325] Animal eat 2016-08-18 19:42:59.468 01-discription[759:669325] Cat eat Program ended with exit code: 0
註解:
1. oc語言是編譯的時候才動態檢測,調用真正的對象,而不管是指針是什麼類型。
2. 父類子針作為參數類型時,其子類子針參數都可以傳入
3. 父類指針指向子類對象不能使用子類獨有的方法,但可以使用強制轉換類型,進而調用