OC對象的三大特性:封裝、繼承和 多態,oc三大
一、封裝
封裝:隱藏對象的屬性和實現細節,僅對外公開介面,控製程序中屬性的讀和修改的存取層級。
person.h:
1 #import <Foundation/Foundation.h>2 3 @interface Person : NSObject4 /** 年齡 */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 : NSObject4 /** 年齡 */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 // 繼承父類Person4 @interface GoodPerson : Person5 /** 姓名 */6 @property (nonatomic, strong) NSString *name;7 8 @end
GoodPerson.m:
1 #import "GoodPerson.h"2 3 @implementation GoodPerson4 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 = LkunProgram 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 : NSObject5 // 餵食動物的方法6 - (void)feedAnimal:(Animal *)animal;7 8 @end
Person.m:
1 #import "Person.h"2 3 @implementation Person4 5 - (void)feedAnimal:(Animal *)animal {6 [animal eat];7 }8 9 @end
Animal.h:
1 #import <Foundation/Foundation.h>2 3 @interface Animal : NSObject4 /** 吃方法 */5 - (void)eat;6 7 @end
Animal.m:
1 #import "Animal.h"2 3 @implementation Animal4 5 - (void)eat {6 NSLog(@"Animal eat");7 }8 9 @end
Cat.h:
1 #import "Animal.h"2 3 @interface Cat : Animal4 5 @end
Cat.m:
1 #import "Cat.h"2 3 @implementation Cat4 #pragma mark - 重寫父類的吃方法5 - (void)eat {6 NSLog(@"Cat eat");7 }8 9 @end
Dog.h:
1 #import "Animal.h"2 3 @interface Dog : Animal4 5 @end
Dog.m:
1 #import "Dog.h"2 3 @implementation Dog4 #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 // 動態檢測真正對象是Dog23 [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 eat2016-08-18 19:42:59.468 01-discription[759:669325] Animal eat2016-08-18 19:42:59.468 01-discription[759:669325] Cat eatProgram ended with exit code: 0
註解:
1. oc語言是編譯的時候才動態檢測,調用真正的對象,而不管是指標是什麼類型。
2. 父類子針作為參數類型時,其子類子針參數都可以傳入
3. 父類指標指向子類對象不能使用子類專屬的方法,但可以使用強制轉換類型,進而調用