Objective-C:06_物件導向-核心文法

來源:互聯網
上載者:User

標籤:des   style   color   io   使用   ar   strong   for   檔案   

點文法:     點文法的本質還是方法調用   當使用點文法時,編譯器會自動延伸成相應的方法      Person *p = [Person new];      p.age=10;  //編譯器編譯的時候會自動將這一行代碼轉換成 [p setAge:10];            int a=p.age;  //編譯器編譯的時候會自動將這一行代碼轉換成 int a  = [p age];        使用點文法的時候要注意不要形成死迴圈:                  - (void)setAge:(int)age

    //下面的代碼將引發死迴圈,相當於[self setAge:age] 
    self.age = age; 

- (int)age 

    //下面的代碼將引發死迴圈,相當於[self age] 
    return self.age; 
}
  成員變數的4種範圍:     @private:只能在當前類的對象方法中直接存取(@implementation中不寫預設是@private) @protected:可以再當前類及其子類的對象方法中直接存取(@interface中不寫預設是@protected) @public:任何地方都可以訪問對象的成員變數@package:只要處在同一個架構中,就能直接存取對象的成員變數,介於@private和@public之間             什麼都不寫的時候預設的存取層級是protected         成員變數也可以寫在實現部分,也就是.m檔案中, 存取層級預設是@private        在 .m檔案中聲明的成員變數不能和 .h檔案中聲明的成員變數重名(也就是@implementation和@interface檔案)         OC中只能單繼承        父類\超類 superclass        子類 subclass\subclasses          @property和@synthesize        這兩個關鍵字是編譯器特性     @property:可以自動產生某個成員變數的set和get方法聲明         成員變數:        int  _age;        int  _height;        NSString *_name;     get和set方法的聲明:         @property  int  age;就相當於下面的兩句聲明代碼         - (void)setAge:(int)age;         - (int)age;         @property NSString *name;         當多個成員變數的類型一致的時候,可以使用 @property 類型  成員1,成員2,成員3;    get和set方法的實現:         @synthesize age=_age; //相當於下面兩個方法(@synthesize自動產生age的set和get方法,並且訪問_age這個成員變數)             如果是@synthesize age;//這樣的寫法的話預設訪問的就不是成員變數_age了,而是成員變數age          -  (void)setAge:(int)age        {            _age=age;        }        - (int)age        {            return _age;        }     不寫成員變數,但是寫@property的話,那麼在@implementation中使用@synthesize的話,訪問成員變數,如果不存在的話,就會自動產生@private的成員變數,資料類型根據@property中的資料類型。(這個變數是產生在@implementation中的)       最簡單的寫法:         直接寫一個@property int age;                 這句話將會完成的任務:                     1、產生age的get和set方法聲明                     2、產生一個int類型的成員變數  int _age;(因為產生的變數是@private,所以如果子類需要訪問的話,還是需要我們自己寫成員變數,這樣就不會產生私人的成員變數了)                     3、產生age的get和set方法的實現      @synthesize的細節       @synthesize age=_age        1、setter和getter實現中會訪問成員變數_age;        2、如果成員變數不存在,就會自動產生一個@private的成員變數_age       @synthesize age          1、setter和getter實現中會訪問age變數          2、如果成員變數age不存在,就會自動產生一個@private的成員變數age       手動實現          1、若手動實現setter方法,編譯器就只會自動產生getter方法          2、若手動實現getter方法,編譯器就只會自動產生setter方法          3、若手動同時實現了setter和getter方法,編譯器就不會自動產生不存在的成員變數         id             id是萬能指標,能指向\操作任何OC對象     id內部包含*,所以聲明變數的時候不需要帶 *    NSString * (字串)也是OC對象,所以id也可以指向字串     也就是說 id 相當於  NSObject  *     id類型的定義:        typedef  struct objc object{            Class isa;        } *id;     局限性:        調用一個不存在的方法的時候,編譯器會馬上報錯   構造方法:對象方法    構造方法:用來初始化對象的方法,是個對象方法,以 -號開頭    重寫構造方法的目的:為了讓對象建立出來,成員變數就會有一些固定的值        Person *p = [Person new];     new方法完整的建立一個對象(分別調用兩個方法完成下面的工作):         1、分配儲存空間(+alloc)         2、初始化(-init)        new方法內部進行的工作:    //調用+alloc方法分配儲存空間    Person *p1 = [Person alloc];    //調用-init方法進行初始化    Person *p2 = [p1  init];     init方法就是構造方法:    等價於:Person *p = [[Person alloc] init];     對象初始化之後,對象的成員變數預設為0     當要求每個Person對象建立出來的時候,他的成員變數_age都是10         構造方法的注意點:         1、先調用父類的構造方法 ([super init])         2、在進行子類內部成員變數的初始化         //重寫-init方法
- (id)init {    //1、一定要調用super的init方法:初始化父類中聲明的一些成員變數和其他屬性       //2、如果對象初始化成功,才有必要進行接下來的初始化     if ( self = [super init] )     {         //初始化成功         _age = 10;     }     //3、返回一個已經初始化完畢的對象     return self; }
  自訂建構函式:    上面的重寫init方法,只能在內部給成員變數賦初始值,聲明的對象都一樣        自訂建構函式分兩步:        第一步:聲明        第二步:實現             自訂構造方法的規範:         1、一定是對象方法,一定以   -   開頭         2、傳回值一般是id類型         3、方法名一般以initWith開頭    聲明:     - (id)initWithName:(NSString *)name;     實現:      - (id)initWithName:(NSString *)name        {            if(self = [super init])            {                _name=name;            }            return self;        }      當子類中的初始化方法需要使用父類的成員變數的時候,原則是:子類中的成員變數在子類中初始化,父類的成員變數在父類中初始化。(父類中提供初始化方法,然後子類將值傳遞過來)        這樣做的好處就是:當父類中的成員變數發生變化的時候,子類不需要更改不會報錯。直接改父類就行了          Category:分類     分類:可以給某一個類擴充一些方法(不修改原來類的代碼)-》相當於C#中的partial          //聲明     @interface 類名 (分類名稱)       @end          //實現     @implementaion 類名 (分類名稱)       @end      使用注意:         1、分類只能增加方法,不能增加成員變數         2、分類方法實現中可以訪問原來類中聲明的成員變數         3、如果分類中的方法與原來類中的方法重名,那麼優先調用的是分類中的方法。(這樣就會覆蓋原來類中的方法,原來類中的方法將不能使用)         4、方法調用的優先順序:分類(最後參與編譯的分類優先)-->原來類-->父類   characterAtIndex:<#(NSUInteger)#>:字串的這個方法是擷取指定位置上的字元(位置序號從0開始)   類的本質:    1、類也是個對象。簡稱 “類對象”        ->其實類也是一個對象,是一個Class類型的對象。             Class關鍵字內部包含 * ,使用的時候後面不需要加 *        利用Person類對象,建立Person類型的對象                 //擷取記憶體中的類對象(擷取到的類對象可以調用類方法)         Person *p = [[Person alloc] init];         Class c = [p class];         或者:Class  c = [Person class];          類的載入過程:         + (void)load:方法,在類被載入的時候調用         程式啟動的時候會載入所有的類和分類,並調用所有類和分類的+load方法         先載入父類,再載入子類,也就是先調用父類的+load,再調用子類的+load         先載入原始類,再載入分類         不管程式運行過程中有沒有用到這個類,都會調用+load載入           +initialize         在第一次使用某個類時(比如建立對象等),就會調用一次+initialize方法         一個類只會調用一次+initialize方法,先調用父類的,在調用子類的          當程式啟動時,就會附加元件目中所有的類和分類,而且載入後會調用每個類和分類的+load方法,先調用原始類的load方法,後調用分類的load方法         當第一次使用某個類時,就會調用當前類的+initialize方法         先載入父類,再載入子類(先調用父類的+load方法,在調用子類的+load方法)             先初始化父類,再初始化子類(先調用父類的+initialize方法,再調用子類的+initialize方法)             description方法:     -description(決定執行個體對象的輸出結果)      Person *p = [[Person alloc] init];    //預設情況下,利用NSLog和%@輸出對象時,結果是: <類名:記憶體位址>    NSLog(@"%@",p);     列印OC對象使用的預留位置是%@    列印OC對象的話(除了NSString *),顯示的是類名加上類在記憶體中的地址        執行NSLog(@"%@",p);這句代碼的時候:        1、首先會調用對象p的-description方法        2、拿到-description方法的傳回值(NSString *)顯示到螢幕上        3、-description方法預設返回的是“類名:記憶體位址”    當想輸出對象的內容的時候,可以在類的實現中重寫-description方法:          - (NSString *)description
{    return [NSString stringWithFormat:@"age=%d,name=%@",_age,_name];}
        不要在description中嘗試輸出self:NSLog(@"%@",self),這樣會引發死迴圈      +description(決定類對象的輸出結果)        Class c = [Person class];     //會調用類的+description方法    //拿到+description方法的傳回值(NSString *)顯示到螢幕上(預設返回的是類名)    NSLog(@"%@",c);      NSLog():        列印指標中儲存的對象的記憶體位址:         NSLog(@"%p",p);     列印指標變數自己的記憶體位址:         NSLog(@"%p", &p);      NSLog()輸出C語言字串的時候,不能有中文        NSLog(@"%s",_func_);//輸出當前方法名稱        NSLog(@"%d",_LINE_);//輸出當前行號        NSLog(@"%s",_FILE_);//輸出當前源檔案的完整路徑        NSLog(@"%s",__PRETTY_FUNCTION__ );//返回當前方法或函數的完整的函數名(包括傳回值和參數)       SEL類型          是一種類型    一個類中都有SEL類型資料,一個SEL資料對應一個方法的地址    Person *p = [[Person alloc] init];    [p test2];        1、把test2封裝成SEL類型的資料    2、根據SEL資料找到對應的方法地址    3、根據方法地址調用對應的方法(這裡使用的緩衝技術,第一次會尋找,以後就會使用第一次尋找的結果)      間接調用test2方法         [p performSelector:@selector(test2)];       方法的儲存位置:        每個類的方法列表都儲存在類對象中        每個方法都有一個與之對應的SEL類型的資料        根據一個SEL對象就可以找到方法的地址,進而調用        SEL類型的定義        typedef struct objc_selector   *SEL;     SEL對象的建立        SEL s= @selector(test);        SEL s2= NSSelectorFormString(@"test");      NSSelectorFormString(@"test");//將一個字串類型的資料傳進去轉換成SEL資料      每個方法內部都有一個SEL類型的資料_cmd,指向當前方法            在方法中不能使用[self performSelector:_cmd];        SEL其實是對方法的一種封裝,將方法封裝成一個SEL類型的資料,去找對應的方法地址,找到方法地址就可以調用方法了。    其實訊息就是SEL      

Objective-C:06_物件導向-核心文法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.