一、构造方法 init
1. 构造方法基本概念
以init开头的方法即为构造方法,主要用于初始化对象。
作用: 对象一被创建就具备某种属性,如年龄设置默认值为10,方式是重写init方法。
2. instancetype 与 id 区别
在使用构造方法,重写init时,返回值是instanceType
区别: 1. 编译时类型的判断: instancetype 在编译时可以判断对象的真实类型,id 不行。
2. 使用: instancetype 只能作为返回值类型。id 既可以做返回值类型,又可以定义变量、做形参。
二、自定义构造方法 initWith
1. 自定义构造方法基本概念
以init开头允许外界创建对象时设置属性,主要用于初始化对象并设置属性。
作用: 构造方法init 创建的对象属性值固定,自定义构造方法允许外界传入设置属性。
-(instancetype)initWithName: (NSString *)name andAge:(int)age
{
self = [super init];
if(self){
_name = name;
_age = age;
}
return self;
}
2. 自定义构造方法在继承中表现
子类 在自定义构造方法中想要在继承父类属性的基础上,新增属性。
注意:谁的事情谁负责,父类的属性由父类初始化
-(instancetype)initWithName: (NSString *)name andAge:(int)age andNum:(int)num
{
self = [super initWithName: name andAge:age];
if(self){
_num = num;
}
return self;
}
}
3. 自定义构造方法中的注意点
问题: 使用中注意到,构造方法中给属性赋值既可以用_num,又可以用self.num, 哪种更好?
引申:self.属性名和_属性名的区别和适用场合
区别:(1) self.属性名,使用点语法自动生成属性对应的setter方法的声明和实现;
_属性名,生成的只是一个变量,成员变量;
(2) 因此,self.属性名访问的是属性的getter方法, 而 _属性名 访问的是地址;
场合:
在init方法即构造方法中,使用_属性名更合适。
因为init方法仅仅是属性的初始化赋值,地址访问更快并且少了getter方法需要进行方法调用的发消息流程。
三、类工厂方法
1. 类工厂方法基本概念
快速创建对象有两种方式:构造方法 和 类工厂方法
作用: 自定义类工厂方法,通过类方法快速创建对象。
+(instancetype)personWithName: (NSString *)name
{
Person *p = [[Person alloc] init];
p.age = age;
return p;
}
2. 类工厂方法在继承中注意点
子类 继承父类的类工厂方法,并新增属性。
注意 类工厂方法在定义时,使用self 而不是具体的类。防止继承中出现真实类型是父类,但是调用的是子类的属性的setter方法:
+(instancetype)personWithName: (NSString *)name
{
Person *p = [[self alloc] init]; // 此处应用self, 否则创建的真实类型就是Person 而不是子类
p.age = age;
return p;
}
int main(int argc, const char *argv[])
{
Son *s = [Son personWithName:@"wang"];
NSLog(@" s.age = %@", s.age);
}