一、 构造方法
构造方法:在OC中init开头的方法, 我们称之为构造方法
构造方法的用途: 用于初始化一个对象, 让某个对象一创建出来就拥有某些属性和值
// 比如我们定义一个Person的类,然后在类里面定义一个age的变量。如果不使用构造方法,有需求创建5个人,每个人年龄初始化为6,这么我们就需要下面的6句代码。 Person *p = [[Person alloc] init]; // p.age = 6; NSLog(@"%i", p.age); Person *p2 = [[Person alloc] init]; // p2.age = 6; NSLog(@"%i", p2.age); Person *p3 = [[Person alloc] init]; // p3.age = 6; NSLog(@"%i", p3.age); // 如果使用构造方法的话,我们再init方法中将_age 初始化,这样就不用再赋值了,这是最简单的应用。 - (instancetype)init { self = [super init]; // self == nil == 0 if (self) { // 初始化子类 _age = 6; } return self; }
需要注意的是重写init方法有固定的格式,如果不按照苹果这个格式来,编译无法通过,记住就行了。
重写init方法, 在init方法中初始化成员变量
注意: 重写init方法必须按照苹果规定的格式重写, 如果不按照规定会引发一些未知的错误
1.必须先初始化父类, 再初始化子类
2.必须判断父类是否初始化成功, 只有父类初始化成功才能继续初始化子类
3.返回当前对象的地址
- (instancetype)init { // 1.初始化父类 // 只要父类初始化成功 , 就会返回对应的地址, 如果初始化失败, 就会返回nil // nil == 0 == 假 == 没有初始化成功 self = [super init]; // 2.判断父类是否初始化成功 if (self != nil) { // 3.初始化子类 // 设置属性的值 _age = 6; } // 4.返回地址 return self; }
如果该构造方法需要我们自己自定义,比如,不想一创建出来的年龄是6,而是工程师自己传入的值就需要自定义了,格式也必须是固定的
// 必须以init开头,With必须大写。 - (instancetype)initWithAge:(int)age { if (self = [super init]) { _age = age; } return self; }
如果涉及到继承,比如,Student 继承自 Person,
// Person类中有方法:- (instancetype)initWithAge:(int)age; // Student中有方法:- (instancetype)initWithAge:(int)age andName:(NSString *)name andNo:(int)no; 继承自父类,但是自己多了name和no(number)属性 // student 继承自 person,我们需要设置以下内容 Student *stu = [[Student alloc] initWithAge:30 andName:@"lnj" andNo:888]; // 那么我们在父类和子类中应该分别写上一下代码,自己的事情自己做,子类别干涉父类的方法 // person 父类方法 - (instancetype)initWithAge:(int)age // 注意: 自定义构造方法中的init后面的With的W一定要大写 //- (instancetype)initwithAge:(int)age { if (self = [super init]) { _age = age; } return self; } // student 子类方法 - (instancetype)initWithAge:(int)age andName:(NSString *)name andNo:(int)no { /* 别这样写,设置父类的代码就让父类来做,自己就设置自己的参数就行了 if (self = [super init]) { // _age = age; // 狗拿耗子, 多管闲事 // 自己的事情自己做 [self setAge:age]; [self setName:name]; } */ if (self = [super initWithAge:age andName:name]) { _no = no; } return self; }
二、类工厂方法
// 如果仔细观察,iOS构造方法,一般都会对应一个类工厂方法,方便程序员交流,减少代码量 + (instancetype)person { // return [[Person alloc] init]; // 注意: 以后但凡自定义类工厂方法, 在类工厂方法中创建对象一定不要使用类名来创建 // 一定要使用self来创建,这样,如果是person的子类来调用该方法,self就代表子类,不然就是person,不符合我们本意 // self在类方法中就代表类对象, 到底代表哪一个类对象呢? // 谁调用当前方法, self就代表谁 return [[self alloc] init]; } + (instancetype)personWithAge:(int)age { // Person *p = [[Person alloc] init]; Person *p = [[self alloc] init]; p.age = age; return p; }