OC04核心語法總結 1


一、 點語法

知識點

1.用點語法替換set和get方法
    1)獲取年齡:[p age];設置:[p setAge:10];
    2)用點語法替代1):p.age=10;
    3)原理:不是訪問成員變量 ,訪問成員變量用->;當編譯器遇到點語法時,會自動展開爲1)的形式[p setAge:10];
    即點語法的本質是:方法調用;
    4)int a=p.age;//等價於get方法;賦值時轉化set;取值時轉化get;
2.驗證是調用了set和get方法:
    1)在set和get放來句打印
    2)設置斷點,進入方法:點擊 “下箭頭的” 進入
    3).出現動態變量的值:點擊分欄效果
3.點語法的注意點
    1)在set方法裏:self.age=age;
    //後果:[self setAge:age];
    //死循環,點擊stop停止,點擊clear 清除
    2)在get方法裏:self.age;
    //後果:[self age];
    //死循環,點擊stop停止,點擊clear 清除
    3)點語法就是set和get方法;沒有相應的set和get方法 不能用 會報錯

代碼舉例

//Person.h
#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    int _age;
    NSString *_name;
}

- (void)setAge:(int)age;
- (int)age;


- (void)setName:(NSString *)name;
- (NSString *)name;

@end
//Person.m
#import "Person.h"

@implementation Person

- (void)setAge:(int)age
{
    //_age = age;

    NSLog(@"setAge:");

    // 會引發死循環
    //self.age = age; // [self setAge:age];
}

- (int)age
{
    NSLog(@"age");
    return _age;
    // 會引發死循環
    //return self.age;// [self age];
}

- (void)setName:(NSString *)name
{
    _name = name;
}

- (NSString *)name
{
    return _name;
}

@end
//main.m

#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, const char * argv[])
{
    Person *p = [Person new];

    // 點語法的本質還是方法調用
    p.age = 10; // [p setAge:10];

    int a = p.age; // [p age];


    p.name = @"Jack";

    NSString *s = p.name;

    NSLog(@"%@", s);

    return 0;
}

二、 成員變量

知識點

1.作用域就是在什麼範圍能直接訪問成員變量:*在(類的實現裏)對象方法裏可以直接訪問(直接就是通過變量名訪問)

2.成員變量的作用域 4種
    1)@private //只能在當前類的對象方法裏可以直接訪問 所以main裏不可以訪問;
    子類方法裏也不能,但是子類內存裏還是有這個成員變量的 (instance:實例)
    但是想訪問這個變量呢?:通過父類的set和get方法訪問
    2)@protected//能在當前類和子類的對象方法裏可以直接訪問 所以main裏不可以訪問 (instance:實例)默認的
    3)@public//意味着在任何地方都可以訪問 比如實現文件裏; main裏
    4)@pakeage//介於私有和公共的,如果我的類和你的類處於一個框架裏,我可以直接訪問你的成員變量

3.一次寫 作用於 下面所有
4.實現裏 也可以寫成員變量(但是不能和聲明裏的重名) 但是默認是私有的。
因爲沒人會包含.m文件,就也不會用到,所以其他作用域符沒意義了;但是成員變量外面要有{};
5.在main之前,可以直接寫類的實現繼承NSObject ;裏面寫成員變量和相關方法 (就是說類的聲明可以不寫,但是不建議這樣)
這時其他作用域符起作用的
6.只要看得見,才能拿來用。否則,不行
7.繼承:也會把類實現裏成員變量繼承過來,屬於單繼承(避免多繼承中不同類出現相同的東西,不好區分)
8.父類==超類:superclass ;子類:subclass/subclasses

代碼舉例

#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    int _no;

    @public // 在任何地方都能直接訪問對象的成員變量
    int _age;


    @private  // 只能在當前類的對象方法中直接訪問
    int _height;

    @protected // 能在當前類和子類的對象方法中直接訪問
    int _weight;
    int _money;
}

- (void)setHeight:(int)height;
- (int)height;

- (void)test;
@end

三、 @property和@synthesize

知識點

1.自動生成setter和getter方法聲明:
    @propert int age;//編譯器特性,遇到自動展開set和get方法聲明 格式: @property 類型 名字;
2.自動生成setter和getter方法實現:
    @synthesize age=_age;//編譯器特性,遇到自動展開set和get方法實現 
    格式: @synthesize 名字1=成員變量1[, 名字2=成員變量2];
    (名字要和@property的一樣)可以連着寫
3.P:property C:class 

4.最簡單的寫法:
    1)同類型的寫在一起
    2)@synthesize 名字1=成員變量1;不寫成員變量1,會自動生成@private的成員變量1,子類不能訪問
    3)成員變量和setter和getter方法一起搞定:@property int age;

5.細節
    1)用越少的代碼去實現更強大的功能。
    2)@synthesize 名字1;//代表會訪問和"名字1"一樣的成員變量 ,不存在就會自動生成"名字1"的成員變量 
    3)@property只能寫在interface裏 @synthesize只能寫在@implementation裏
    4)生成原則:沒有幫你生成,有,則不生成任何東西,不存在的成員變量也不會生成

代碼舉例

//.h裏的@property
#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    int _age;
    // int age;

    int _height;

    double _weight;

    NSString *_name;
}

// @property:可以自動生成某個成員變量的setter和getter聲明
@property int age;
//- (void)setAge:(int)age;自己寫
//- (int)age;


@property int height;
//- (void)setHeight:(int)height; 自己寫
//- (int)height;

- (void)test;


@property double weight;//利用@property參數

@property NSString *name;

@end
//.m裏的@synthesize
#import "Person.h"

@implementation Person

// @synthesize自動生成age的setter和getter實現,並且會訪問_age這個成員變量
@synthesize age = _age;

@synthesize height = _height;

@synthesize weight = _weight, name = _name;

@end

四、 id類型

知識點

1.可以定義變量,變量名不能寫成id
2.id是萬能指針,能指向/操縱任何OC對象
3.不用寫* 星號
4.頭文件裏 @property int age;
5.id d=[Person new];//萬能
6.NSObject *o=[Person new];//多態
7.id相當於 NSObject * (所有OC)類 *
8.void test(id d);//任何對象都能傳進來
9.@perproty id  d;//頭文件裏

五、 構造方法

知識點1:構造方法基本概念

1.一般情況下 創建對象 [Person new];
2.完整的創建一個可用的對象 1)分配存儲空間 +alloc 2)初始化 - init
3.new 方法 內部分別調用兩個方法 實現1)2)
4.按住 option 點擊方法 進入方法;或者雙擊方法名 看右邊 波浪線的圖標
5.(2.1)Person * p1=[Person alloc];//分配空間並返回一個Person類型的新對象
(2.2)p1=[p1 init];//返回一個初始化好的對象
6.用new 只能用init進行初始化,所以分開使用,可以選擇自己的方法去初始化
7.Person *p3=[[Person alloc] init];//可以這樣寫,建議這樣寫
8.init就是構造方法,用來初始化對象的方法就是構造方法,肯定是一個對象方法 - 減號開頭

知識點2:重寫init方法

1.每次創建Person對象出來都要保證變量age有個固定的值10
2.默認的init時父類NSObject的
3.command+雙擊類:快速進入類的頭文件
4.在類實現.m文件裏 重新實現init方法(不用寫聲明瞭,因爲父類聲明過了)
- (id)init//因爲子類類型不確定
{
    /*self=[super init] 1.一定要調用回super的init的方法;
    是爲了初始化當前super(對象的父類)中聲明的成員變量和其他屬性 ,返回就是當前對象self*/
    if(self=[super init])
    //*2 if(self)
    //*1.if(self != nil)//nil0 (寫法:12→最簡單)
    {
    //初始化成功,能進行下面的初始化賦值給變量
        _age=10;
    }
    return self;//返回一個已經初始化完畢的對象
}

子類可以自己拓展自己的屬性

//學生對象初始化後,年齡(父類的變量)就是10 學號就是1
- (id) init
{
if(self=[super init])
{
_no=1;
}
return self
}//學生最終擁有的成員變量:自己的,和所有父類的SObject是不能step into去方法的
1.構造方法,先會初始化父類的東西,再初始化自己的 從上到下 初始化
2.重寫構造方法的目的:爲了讓對象創建出來,成員變量就會有一些固定的值
3.注意點:在重寫的init方法裏先去調用父類的構造方法([super init]);;在進行子類內部成員變量的初始化
4.init方法的執行過程:isa 是動態改變的 總是指向當前調用者的類

知識點3:自定義構造方法

1.先寫代碼 在寫右邊中括號 會自動補齊
2.重寫的init會把成員變量默認值定死,這樣不好,最好是根據外界所傳,默認值就是什麼 這就引入了自定義的構造方法
3.規範:
    1*一定是對象方法 - 開頭 
    2*返回值一般是id類型 
    3*方法名一般以init開頭
    4*成員變量 以_下劃線開頭 特色
- (id)initWithName:(NSString *)name
{
    if(self=[super init])
       {
        _name=name;
    }
    return self;
}
5.如果_name是父類通過@property生成的,就說明它使私有的,不能在子類直接使用 
 所以要通過setter和getter方法訪問 改成 [self setAge:name] 
(這樣寫優先在在子類找setAge方法)或者self.age; 或者  [super setAge:name]
-  (id)initWithName:(NSString *)name andAge:(int) age
{
    if(self=[super init])
    {
        _name=name;

        _age=age;
    }
    return self;
}
6.一個子類方法想同時初始化父類的成員變量,要注意父類的成員變量能否直接訪問,不能就用父類的setter和getter方法
-  (id)initWithName:(NSString *)name andAge:(int) age
{
    if(self=[super initWithName:name])//父類的屬性交給父類去初始化,這樣寫比5的好處是,
    //父類的成員變量變化不會影響子類的代碼變化
    {
        _age=age;
    }
    return self;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章