018-繼承-OC筆記


學習目標

1.【掌握】Xcode開發文檔

2.【掌握】static關鍵字

3.【掌握】self關鍵字

4.【掌握】繼承

5.【掌握】NSObject

6.【掌握】訪問修飾符

7.【掌握】私有實例變量和私有方法

8.【掌握】多態

9.【掌握】description

一、Xcode開發文檔

蘋果提供了很多的框架,每個框架中有很多類,每個類有很多方法,每個方法也有各種不同的用法。我們怎么查看這些框架里的這些類里的這些方法呢?蘋果為我們提供了一個全面、豐富、牛逼的開發文檔,只要我們裝上就能隨時查看了。

安裝和查看文檔

在線安裝:Xcode -> Preferences -> Downloads ->Documentation,選中需要下載的直接下載,國內下載非常慢。(不推薦)

離線安裝:網上下載離線包,復制到文檔路徑:

/Applications/Xcode.app/Contents/Developer/Documentation/DocSets里。(推薦)

查看文檔:Window -> Documentation and API Reference 里可查看。

二、static關鍵字

static關鍵字在OC中也能使用,但是不能修飾屬性也不能修飾方法。但可以修飾方法內部的局部變量,被static修飾的局部變量是靜態變量,存儲在常量區,當方法執行完畢之后,局部變量不會被回收。下次再聲明的時候不會再重新聲明一次,二是直接使用。

使用場景:當我們需要每次創建學生時就為學生自動賦值學號

Student.h文件

#import
@interface Student : NSObject{    //學號    int _studyId;}//_studyId的get方法聲明- (int)studyId;
//實例化一個對象的類方法聲明+ (Student *)student;@end

Student.m文件

#import "Student.h"
@implementation Student//_studyId的get方法實現- (int)studyId{    return _studyId;}
//實例化一個對象的類方法實現+ (Student *)student{   //將局部變量用static關鍵字修飾為靜態變量    static int studyIdTemp =1;        //實例化一個對象student    Student *student =[Student new];       //為student對象的_studyId實例變量賦值局部變量studyIdTemp    student->_studyId =studyIdTemp;       //每次調用這個類方法實例化一個對象,studyIdTemp自增1    studyIdTemp++;        //返回student對象給調用者    return student;}@end

main.m文件

#import#import "Student.h"
int main(int argc, const char * argv[]) {    @autoreleasepool {       //調用Student的類方法實例化3個對象,會在類方法實現內部自動為學號賦值       Student *student1 = [Student student];       Student *student2 = [Student student];       Student *student3 = [Student student];       NSLog(@"他們的學號分別為student1 = %i student2 = %istudent3 = %i",[student1 studyId],[student2 studyId],[student3studyId]);       //輸出 他們的學號分別為student1 = 1 student2 = 2 student3= 3    }    return 0;}

從上面例子不難得出,當我們希望一個方法內部的局部變量能被多次調用,在方法執行完畢后不被銷毀,這個時候我們就可以使用static來修飾我們的局部變量。

三、self關鍵字

self與對象方法

在方法的實現內,是可以聲明一個和實例變量同名的局部變量,此時局部變量會屏蔽掉同名的實例變量的作用域(在局部變量的作用域范圍內屏蔽掉實例變量的作用域)。但是我們可以使用self來訪問被屏蔽作用域的實例變量,這個時候self指針指向當前對象(誰調用就指向誰)。(PS:我也不知道這樣形容嚴謹不,就是這個意思哈,你懂就行)

如果方法中有一個局部變量和實例變量同名,要訪問實例變量必須使用self,不過我們在開發中一定不要在方法實現內聲明和實例變量同名的變量。

應用案例:

Person.h文件

#import@interface Person : NSObject{    NSString *_name;    int _age;}//_name的set和get方法聲明- (void)setName:(NSString *)name;- (NSString *)name;//_age的set和get方法聲明- (void)setAge:(int)age;- (int)age;@end

Person.m文件

#import "Person.h"@implementation Person//_name的set和get方法實現- (void)setName:(NSString *)name{    NSString *_name =@"同名變量";    self->_name =name;//這里就是將傳入的值賦值給當前對象的實例變量_name}- (NSString *)name{    return _name;}//_age的set和get方法實現- (void)setAge:(int)age{    int _age = 18;    _age =age;//這里不使用self則是賦值給局部變量_age}- (int)age{    return _age;}@end

main.m文件

#import#import "Person.h"int main(int argc, const char * argv[]) {    @autoreleasepool {       //實例化一個p對象,並調用set方法賦值       Person *p = [Person new];       [p setName:@"周劍峰"];       [p setAge:20];              NSLog(@"name = %@ age = %i",[p name],[page]);       //打印出 name = 周劍峰 age = 18       //而不是 name = 周劍峰 age = 20    }    return 0;}

self與類方法

self也可以在類方法中使用,這個時候self指針指向當前類。所以我們就能通過self來調用其他類方法,並且強烈推薦使用這種方式來調用其他類方法,而不是通過類名來調用。

應用案例:

Person.h文件

#import@interface Person : NSObject//聲明兩個類方法+ (void)sayHi;+ (void)sayHello;@end

Person.m文件

#import "Person.h"@implementation Person//在類方法實現里調用另一個類方法+ (void)sayHi{   NSLog(@"類方法sayHi");    [selfsayHello];//建議使用self調用    [PersonsayHello];//不建議使用類名調用}+ (void)sayHello{   NSLog(@"類方法sayHello");}@end

main.m文件

#import#import "Person.h"int main(int argc, const char * argv[]) {    @autoreleasepool {       [Person sayHi];          }    return 0;}

四、繼承

018-繼承-OC筆記

當多個類具有相同成員的時候,那么這個時候就可以把相同的成員抽取出來定義到一個類中,讓其他類繼承這個類。當建立了繼承關系,子類(派生類)就擁有父類(基類)所有成員,並且子類可以重寫父類方法也能新增子類特有的方法和實例變量。

語法:@interface子類類名 : 父類類名

Person.h文件

#import
//性別枚舉typedef enum {    GenderMale,    GenderFemale}Gender;
@interface Person : NSObject{    NSString *_name;    Gender _gender;    int _age;}
//_name的set、get方法聲明- (void)setName:(NSString *)name;- (NSString *)name;
//_gender的set、get方法聲明- (void)setGender:(Gender)gender;- (Gender)gender;
//_age的set、get方法聲明- (void)setAge:(int)age;- (int)age;
//父類吃食物方法聲明- (void)eatWithFoodName:(NSString *)foodName;@end

Person.m文件

#import "Person.h"
@implementation Person
//_name的set、get方法實現- (void)setName:(NSString *)name{    _name = name;}- (NSString *)name{    return _name;}
//_gender的set、get方法實現- (void)setGender:(Gender)gender{    _gender = gender;}- (Gender)gender{    return _gender;}
//_age的set、get方法實現- (void)setAge:(int)age{    _age = age;}- (int)age{    return _age;}
//父類吃食物方法實現- (void)eatWithFoodName:(NSString *)foodName{   NSLog(@"%@吃%@",self->_name,foodName);}@end

Student.h文件

//導入Person類的頭文件#import "Person.h"
//Student類繼承Person類@interface Student : Person{    int _studyId;}
//Student類特有實例變量的set、get方法聲明- (void)setStudyId:(int)studyId;- (int)studyId;
//Student類特有學習方法- (void)study;@end

Student.m文件

#import "Student.h"
@implementation Student
//Student類特有實例變量的set、get方法實現- (void)setStudyId:(int)studyId{    _studyId =studyId;}- (int)studyId{    return _studyId;}
//Student類特有學習方法- (void)study{   NSLog(@"學生類特有的學習方法");}@end

main.m文件

#import#import "Student.h"
int main(int argc, const char * argv[]) {    @autoreleasepool {       Student *stu = [Student new];              //繼承父類的實例變量       [stu setName:@"周劍峰"];       [stu setGender:GenderFemale];       [stu setAge:20];              //學生類的特有實例變量       [stu setStudyId:2];              //輸出學生的信息       NSLog(@"name = %@ gender = %d age = %i studyId =%i",[stu name],[stu gender],[stu age],[stu studyId]);              //繼承父類的方法       [stu eatWithFoodName:@"米飯"];              //子類特有的方法       [stu study];           }    return 0;}

注意:

1.構成繼承關系的類,他們直接應該有所屬關系。比如學生是一個人(學生類繼承人類),狗是一個動物(狗是一個動物)。

2.從父類繼承的方法,不適用於子類時,可以直接聲明父類的同名方法,並定義(這就是重寫方法)。

3.子類重寫方法之后,在調用方法時,父類的對象調用父類的方法,子類的對象調用子類的方法,不會引起沖突。

4.子類重寫方法之后,子類可以通過super關鍵字調用父類的類方法(這里的super也相當於一個指向父類的指針)。

5.只要某個成員不是所有子類都擁有的,那么這個成員就不應該定義在父類中。

6.一個類只能有一個父類,objective-c不支持多繼承。

7.子類和父類中不能有同名的屬性。

8.super關鍵字用在子類對象方法中,可以調用當前子類繼承的父類的對象方法。

9.super關鍵字用在子類的類方法中,可以調用父類的類方法。

繼承的特點

1.單根性:一個類只能有一個父類,objective-c不支持多繼承。

2.傳遞性:當A類繼承B類,B類又繼承自C類。B類繼承了C類所有成員,A類又繼承了B類所有成員(包括B類繼承的C類所有成員)。

五、NSObject

要實例化一個對象,必須要調用這個類的類方法new,而這個方法定義在NSObject之中。所以,為了保證我們的類擁有創建對象的能力,那么我們的類必須直接或間接的從NSObject類繼承。

NSObject類是所有類的基類,在這個類中定義了一個實例變量isa指針,指向代碼區中類的地址。

六、訪問修飾符

訪問修飾符是用來修飾類的實例變量的,被不同訪問修飾符修飾的實例變量的訪問權限是不同的。所以,訪問修飾符的作用就是用來限制實例變量的訪問權限的。

@public 共有的

被@public關鍵字修飾的實例變量可以通過對象名在任意的地方訪問。

@protected 受保護的

被@protected關鍵字修飾的實例變量只能在本類和他的子類訪問。如果實例變量沒有被訪問修飾符修飾,默認修飾符就是@protected。

@private 私有的

被@private關鍵字修飾的實例變量只能在本類的內部訪問,子類能繼承私有成員,但在子類方法實現中無法訪問繼承的私有成員。

@package 包權限

被@package關鍵字修飾的實例變量只能在當前框架中訪問。

七、私有實例變量和私有方法

私有實例變量

將實例變量定義在@implementation中,這些實例變量就是私有實例變量,這些私有實例變量只能在本類中訪問,不能在其他地方訪問,並且Xcode都不提示類中存在的私有實例變量。注意:這種情況可以在子類中定義和父類私有實例變量同名的實例變量。

@implementation Person

{

    NSString *_name;

    //定義在這里的實例變量只能在本類中訪問

}

@end

私有方法

沒有方法的聲明,只有方法的實現。這樣的方法就只能在類的內部調用。

八、多態

多態就是父類指針指向子類對象

1.當方法的參數是一個父類類型的時候,那么傳遞的實參可以是父類對象也可以是子類對象。

2.當一個父類指針指向一個子類對象的時候,只能通過父類指針訪問子類對象中的繼承成員,子類獨有的不能訪問。

多態的好處

多態的主要好處就是簡化了編程接口。它容許在類和類之間重用一些習慣性的命名,而不用為每一個新加的函數命名一個新名字。這樣,編程接口就是一些抽象的行為的集合,從而和實現接口的類的區分開來。

多態也使得代碼可以分散在不同的對象中而不用試圖在一個函數中考慮到所有可能的對象。這樣使得代碼擴展性和復用性更好一些。當一個新的情景出現時,無須對現有的代碼進行改動,而只需要增加一個新的類和新的同名方法。

九、description

%@是專門用來輸出對象的,默認情況下,我們將對象以%@的格式輸出,輸出的是

<對象所屬的類名:對象的地址>

NSLog(@"%@",對象名);輸出一個對象的時候,會先調用傳入對象的description方法,這個方法的返回值是字符串(NSString*),然后將這個字符串輸出。我們可以重寫description方法,輸出我們需要輸出的任意內容。

- (NSString *)description{

    NSString *str =@"<<重寫了description方法>>";

    return str;

}

這個時候我們在使用NSLog(@"%@",對象名);輸出的是

<<重寫了description方法>>

溫馨提示:歡迎分享本文,轉載請保留出處!


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com