對象是對客觀事物的抽象,類是對對象的抽象。類是一種抽象的資料類型
面向對象的程式設計語言都是有類及對象的
類是由屬性及方法組成。
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),下一篇會說繼承
一個标準的自定義類就是這樣來寫,具體遇到問題遇到什麼需求可以适當的做些改變