天天看點

Snail—OC學習之類及對象

對象是對客觀事物的抽象,類是對對象的抽象。類是一種抽象的資料類型

面向對象的程式設計語言都是有類及對象的

類是由屬性及方法組成。

OC中的所有官方類及自定義的類都是NSObject的直接或者間接子類

下面看看類的編寫規範

首先,COMMAND+N 建立一個類 Dog類

看到會生成兩個檔案.h和.m

.h是對屬性及方法的聲明,.m是對方法實作.

Dog.h檔案中編寫如下  

#import <Foundation/Foundation.h>

@interface Dog : NSObject{
    //名字的變量 類型是字元串
    NSString *_name;
    //性别暫時用int值代替 1代表公 0代表母
    int _sex;
    
}


// 前面是+号,即此函數是Dog類的方法 可以直接用Dog類名來調用
// 無需建立對象就可以調用,簡化代碼
//另一個作用就是用來建立單例,即在整個生命周期,無論建立多少次都是同一個對象
+ (instancetype)sharedDog;

// 前面是-号的叫做對象方法
//預設的無參構造函數  如果不寫 也是會存在的預設構造函數
- (instancetype)init;
//帶一個參數的構造函數
- (instancetype)initWithName:(NSString *)name;
//帶兩個參數的構造函數
- (instancetype)initWithName:(NSString *)name AndSex:(int)sex;


//對象變量name、sex的get及set方法
- (void)setName:(NSString *)name;
- (NSString *)name;
- (void)setSex:(int)sex;
- (int)sex;


// 狗的一個行為
// bark(叫) 傳回值為void空,無參
- (void)bark;

//lookHome(看家)無參
- (void)lookHome;

@end
           

Dog.m代碼編寫如下

#import "Dog.h"

@implementation Dog


// 由此可見,利用Dog類名來調用這個方法時 無論建立多少次對象都是同一個dog
+ (instancetype)sharedDog{
    static Dog * dog;
    if (dog != nil) {
        dog = [[Dog alloc] init];
    }
    return dog;
}

//init開頭的方法都是初始化構造函數 一種編碼規範
// init是沒有參數的預設寫法
- (instancetype)init{
    if (self = [super init]) {
    }
    return self;
}

//這是具有一個參數的初始化構造函數
- (instancetype)initWithName:(NSString *)name{
    if (self = [super init]) {
        _name = name;
    }
    return self;
}

//具有兩個參數的構造函數
- (instancetype)initWithName:(NSString *)name AndSex:(int)sex{
    if (self = [super init]) {
        _name = name;
        _sex = sex;
    }
    return self;
}


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

- (void)setSex:(int)sex{
    _sex = sex;
}

- (int)sex{
    return _sex;
}

- (NSString *)name{
    return _name;
}

//叫得方法 實作
- (void)bark{
    //在類的方法中可以通路成員變量,也可以指派
    _name = @"刀刀";
    NSLog(@"%@在叫!",_name);
}

- (void)lookHome{
    _sex = 1;
    NSLog(@"刀刀狗是個%d的",_sex);
}


@end
           

main函數引入頭檔案後建立幾個對象

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

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        Dog * dog1 = [Dog sharedDog];
        [dog1 setName:@"刀刀"];
        [dog1 setSex:1];
        //%p可以列印出對象的位址 0x100106800
        NSLog(@"%p",dog1);
        Dog * dog2 = [Dog sharedDog];
        //0x100106800  dog2的位址和dog1的位址一樣 即是同一個對象
        NSLog(@"%p",dog2);
        
        //當我們在main函數即相對于Dog類來說的外界函數 我們無法調用self.name的 我們通過set/get來對變量進行指派或者擷取

        // alloc 是在堆空間開辟一塊空間 然後init初始化對象
        Dog * dog3 = [[Dog alloc] init];
        //下面指派可以這樣寫 dog3.name = @"汪星人";
        //原理就是此語句調用的下面這個方法 調用了 -(void)setName:(NSString *)name;
        [dog3 setName:@"汪星人"];
        //下面dog3.name 的作用跟 [dog name]一樣
        //其實前者這樣寫的原理就是調用了後者 調用了(NSString *)name方法
        NSString * name = dog3.name;
        NSLog(@"%@",name);
        //dog3調用直接的bark(叫)的方法
        [dog3 bark];
        
        //有參的初始化方法
        Dog * dog4 = [[Dog alloc] initWithName:@"大黃" AndSex:8];
        NSLog(@"我是%@",dog4.name);
        
        
    }
    return 0;
}
           

下面,來介紹一個知識點,即property屬性修飾

改寫一下Dog類

首先,Dog.h中 改寫成下面這樣

#import <Foundation/Foundation.h>

@interface Dog : NSObject{
    
}

@property NSString * name;
@property int sex;


// 前面是+号,即此函數是Dog類的方法 可以直接用Dog類名來調用
// 無需建立對象就可以調用,簡化代碼
//另一個作用就是用來建立單例,即在整個生命周期,無論建立多少次都是同一個對象
+ (instancetype)sharedDog;

// 前面是-号的叫做對象方法
//預設的無參構造函數  如果不寫 也是會存在的預設構造函數
- (instancetype)init;
//帶一個參數的構造函數
- (instancetype)initWithName:(NSString *)name;
//帶兩個參數的構造函數
- (instancetype)initWithName:(NSString *)name AndSex:(int)sex;


// 狗的一個行為
// bark(叫) 傳回值為void空,無參
- (void)bark;

//lookHome(看家)無參
- (void)lookHome;

@end
           

Dog.m檔案中

#import "Dog.h"

@implementation Dog


// 由此可見,利用Dog類名來調用這個方法時 無論建立多少次對象都是同一個dog
+ (instancetype)sharedDog{
    static Dog * dog;
    if (dog == nil) {
        dog = [[Dog alloc] init];
    }
    return dog;
}

//init開頭的方法都是初始化構造函數 一種編碼規範
// init是沒有參數的預設寫法
- (instancetype)init{
    if (self = [super init]) {
    }
    return self;
}

//這是具有一個參數的初始化構造函數
- (instancetype)initWithName:(NSString *)name{
    if (self = [super init]) {
        name = name;
    }
    return self;
}

//具有兩個參數的構造函數
- (instancetype)initWithName:(NSString *)name AndSex:(int)sex{
    if (self = [super init]) {
        self.name = name;
        self.sex = sex;
    }
    return self;
}



//叫得方法 實作
- (void)bark{
    //在類的方法中可以通路成員變量,也可以指派
    self.name = @"刀刀";
    NSLog(@"%@在叫!",_name);
}

- (void)lookHome{
    self.sex = 1;
    NSLog(@"刀刀狗是個%d的",_sex);
}


@end
           

可以看出來 變量、及變量的get/set方法代碼删除後, 利用property來修飾的屬性 再執行main.m檔案時 沒有報錯 即property自動為我們生成了set/get方法

這就是一個自定義的類。此類是直接繼承于NSObject父類的(@interface Dog : NSObject),下一篇會說繼承

一個标準的自定義類就是這樣來寫,具體遇到問題遇到什麼需求可以适當的做些改變