第一部分 封裝 一、封裝的作用 1、過濾不合理的值
2、屏蔽内部的指派過程
3、讓外界不必關注内部的細節
二、set方法和get方法 1、使用場合 被@public修飾的成員變量可以在任何位置随意的指派,這樣很不安全,我們應該使用set方法和get方法來管理成員變量的通路。
#import <Foundation/Foundation.h>
@interface Student : NSObject
{
int _age;
}
- (void)setAge:(int)age; //set方法
- (int)age; //get方法
@end
@implementation Student
// set方法的實作
- (void)setAge:(int)age
{
// 對傳進來的參數進行過濾
if (age <= 0)
{
age = 1;
}
_age = age;
}
// get方法的實作
- (int)age
{
return _age;
}
@end
int main()
{
Student *stu = [Student new];
[stu setAge:-10];
NSLog(@"學生的年齡是%d歲", [stu age]);
return 0;
}
// 學生的年齡是1歲,因為在set方法中,會對傳入的參數過濾,-10歲這樣的年齡不合理。
2、成員變量的命名規範 (1)一定要以下劃線 _ 開頭
(2)作用:
1> 讓成員變量和get方法的名稱區分開
2> 可以跟局部變量區分開,一看到下劃線開頭的變量,一般都是成員變量
3、set方法 (1)作用:提供一個方法給外界設定成員屬性值,可以在方法裡面對參數進行相應過濾
(2)命名規範:
1> 方法名必須以set開頭
2> set後面跟上成員變量的名稱,成員變量的首字母必須大寫
3> 傳回值一定是void
4> 一定要接收一個參數,而且參數類型跟成員變量類型一緻
5> 形參的名稱不能跟成員變量名一樣
4、get方法 (1)作用:傳回對象内部的成員變量
(2)命名規範:
1> 肯定有傳回值,傳回值類型肯定與成員變量類型一緻
2> 方法名跟成員變量名一樣
3> 不需要接收任何參數
三、類方法
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
int age;
}
// 類方法是以+開頭
- (void)test;
+ (void)test;
@end
@implementation Person
- (void)test
{
NSLog(@"111");
}
+ (void)test
{
NSLog(@"333"); //不能通路成員變量
}
@end
int main()
{
Person *p = [Person new];
[p test]; //對象方法調用
[Person test]; //類方法調用
return 0;
}
1、類方法的命名規範 (1)加号 + 開頭
(2)方法隻能由類(名)調用
(3)類方法中不能通路執行個體變量(成員變量)
2、與對象方法的差別以及優點 (1)對象方法
1> 減号 - 開頭
2> 隻能由對象來調用
3> 對象方法中能通路目前對象的執行個體變量(成員變量)
(2)優點 1> 不依賴于對象,執行效率高
2> 能用類方法盡量用類方法
3> 類方法和對象方法的名字可以相同 3、使用場合 當方法内部不需要使用到成員變量時,就可以改為類方法
四、self關鍵字 1、self是指針,指向目前方法的調用者 2、self的用途
(1)誰調用了目前方法,self就代表誰
1> self出現在對象方法中,self就代表對象
2> self出現在類方法中,self就代表類
(2)在對象方法中利用"self->成員變量名"通路目前對象内部的成員變量
(3)[self 方法名]可以調用其他對象方法或者類方法;
1> 如果在對象方法中,可以調用類方法
2> 如果在類方法中,一定不能調用對象方法 第二部分 繼承 一、繼承的格式以及優點
#import <Foundation/Foundation.h>
/******** Animal的聲明 ********/
@interface Animal : NSObject
{
int _age;
}
- (void)setAge:(int)age;
- (int)age;
@end
/******** Animal的實作 ********/
@implementation Animal
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}
@end
/******** Dog ********/
@interface Dog : Animal //Dog是子類,Animal是父類,子類繼承父類
@end
@implementation Dog
@end
int main()
{
Dog *d = [Dog new];
[d setAge:10];
NSLog(@"age=%d", [d age]);
return 0;
}
1、繼承的基本使用 (1)子類方法和屬性的通路過程:如果子類沒有,就去通路父類的 (2)雖然被繼承了,但是父類中的執行個體變量和方法還是能繼續使用 2、繼承的好處:
(1)抽取重複代碼
(2)建立了類之間的關系,Dog是Animal的子類,Animal是Dog的父類。
(3)子類可以使用父類中的所有成員變量和方法,Dog : Animal,繼承了Animal,相當于擁有了Animal裡面的所有成員變量和方法。
3、繼承的細節: (1)基本上所有類的根類是NSObject
(2)不允許子類和父類擁有相同名稱的成員變量 4、重寫: (1)子類重新實作父類中的某個方法,覆寫父類以前的做法 (2)注意點 1> 父類必須聲明在子類的前面,不用管父類的實作。
2> 調用某個方法時,優先去目前類中找,如果找不到,就去父類中找。
(3)super關鍵字 1> 使用場合:在子類方法中,想直接調用父類方法 2> 注意:super處在對象方法中,那麼就會調用父類的對象方法;super處在類方法中,那麼就會調用父類的類方法
5、繼承的使用場合 (1)當B類是A類的時候,就讓B類繼承A類
@interface Person : NSObject //A類:人
@end
@interface Student : Person //B類:學生
@end
(2)當B類擁有A類的時候,就寫成組合
@interface Car : : NSObject //A類:車
{
int _speed; //速度
int _wheels; //輪子
}
@end
@interface Person : NSObject //B類:人
{
Car *_car; // 人擁有車
int _age; //年齡
}
@end
第三部分 多态 一、多态的基本使用
#import <Foundation/Foundation.h>
@interface Animal : NSObject
- (void)eat;
@end
@implementation Animal
- (void)eat
{
NSLog(@"Animal-eat!");
}
@end
@interface Dog : Animal
@end
@implementation Dog
- (void)eat
{
NSLog(@"Dog-eat!");
}
@end
int main()
{
Dog *d = [Dog new];
// 多種形态
Animal *a = [Dog new];
[a eat]; // Dog-eat!
return 0;
}
1、子類對象指派給父類指針 2、調用方法時,會檢測對象的真實形象,在運作時根據對象的類型确定動态調用的方法。雖然指針是父類,但是對象實際是子類,那麼會去子類裡面找eat方法
二、多态的好處
void feed (Animal *aa)
{
[a eat];
}
Animal *a = [Animal new];
feed(a); //Animal-eat!
Dog *d = [Dog new];
feed(d); //Dog-eat!
1、如果參數中使用的是父類類型,可以傳入父類、子類對象,節省代碼 2、傳入以後,會檢測對象的真實形象,然後執行方法
三、多态的局限性 1、父類類型指針變量不能直接調用子類對象中特有的方法
// 狗類特有的方法
- (void)run
{
NSLog(@"Dog-run!");
}
Animal *a = [Dog new];
// 編譯器會警告Animal類中沒有run這個方法
// [a run];
2、把父類強轉成子類,才可以調用。
// 将a轉為Dog *類型的變量
Dog *dd = (Dog *)a;
[dd run];