前面我们用OC的类创建对象的时候我们用的是new方法。其实new方法是一个组合的方法,它是由两个方法组合在一块的,分别是alloc方法和init方法。其中alloc方法是类方法,它是用来给对象分配一个存储空间的,init方法是对象方法,它是用来对对象进行初始化的,init方法也叫做构造方法。
在OC中,我们通常要重写init方法以便在初始化的时候就给成员变量赋上一些值,所以我们在创建对象的时候最好不要用new方法,因为这样我们就不能重写构造方法了。那么怎么重写init方法呢?重写init方法的步骤:
1、调用父类的init方法。这是为了先初始化父类中声明的成员变量和其他属性。
2、判断对象是否初始化成功,成功的话再对子类的成员变量进行初始化。
3、返回初始化的对象。
下面我们创建一个Person类,类中定义了一个int类型的成员变量_age,下面我们创建一个Person类的对象并对其初始化,使_age的值为20。
[objc] view plaincopy
- #import <Foundation/Foundation.h>
- // Person类的声明
- @interface Person : NSObject
- @property int age;
- @end
- // Person类的实现
- @implementation Person
- // 重写init方法
- - (id)init
- {
- // 判断父类的初始化是否完成,完成的话对_age进行初始化
- if (self = [super init]) {
- _age = 20;
- }
- // 返回初始化完成后的对象
- return self;
- }
- @end
- int main()
- {
- // 创建一个Person类的对象
- Person *p = [[Person alloc] init];
- // 输出_age的值
- NSLog(@"_age = %d", p.age);
- return 0;
- }
上面是对Person类的p对象进行初始化并使_age的值在初始化完成后就是20。
重写init方法的注意点:先调用父类的init方法[super init],再对子类的成员变量初始化。
那么我们可不可以不在类中给成员变量赋初值,而是在其他地方赋值呢?
在其他地方赋初值的话就要重新定义init方法,下面我们学习在main函数中传入成员变量的初值。
[objc] view plaincopy
- #import <Foundation/Foundation.h>
- @interface Person : NSObject
- @property int age;
- // 重新设计构造方法需要先声明
- - (id)initWithAge:(int)age;
- @end
- @implementation Person
- // 重新设计的构造方法并初始化_age
- - (id)initWithAge:(int)age
- {
- if (self = [super init]) {
- _age = age;
- }
- return self;
- }
- @end
- int main()
- {
- // 创建一个Person类的对象,调用重新设计的构造方法并传入赋给_age的值
- Person *p = [[Person alloc] initWithAge:23];
- // 输出_age的值
- NSLog(@"_age = %d", p.age);
- return 0;
- }
上面代码输出结果是:
_age = 23
自定义构造方法的注意点是:
1、以“-”号开头,也就是必须是对象方法。
2、返回值一般是id类型。
3、方法名一般以initWith开头。
下面我们学习子类继承父类时怎么设计构造方法。
[objc] view plaincopy
- #import <Foundation/Foundation.h>
- // Person类的声明和实现
- @interface Person : NSObject
- @property int age;
- // 设计的构造方法的声明
- - (id)initWithAge:(int)age;
- @end
- @implementation Person
- // 设计的构造方法的实现
- - (id)initWithAge:(int)age
- {
- if (self = [super init]) {
- _age = age;
- }
- return self;
- }
- @end
- // Student类的声明和实现
- @interface Student : Person
- @property double score;
- // 设计的构造函数的声明
- - (id)initWithAge:(int)age andScore:(double)score;
- @end
- @implementation Student
- // 设计的构造方法的实现
- - (id)initWithAge:(int)age andScore:(double)score
- {
- //调用了父类重新设计的构造方法
- if (self = [super initWithAge:age]) {
- _score = score;
- }
- return self;
- }
- @end
- int main()
- {
- // 创建一个Student类的对象,调用重新设计的构造方法并传入_age和_score的值。
- Student *s = [[Student alloc] initWithAge:18 andScore:92];
- // 输出_age的值
- NSLog(@"_age = %d, _score = %.1f", s.age, s.score);
- return 0;
- }
上面的代码的重点是在子类的构造方法中调用了父类的构造方法。在设计构造方法中,如果子类需要对父类的成员变量进行初始化且父类中已经定义了对该成员变量初始化的init方法,我们就要调用父类的构造方法。也就是说,父类的属性交给父类来处理,子类的给子类来处理。
以上就是构造方法的简单介绍。我们来总结几个重点:
1、如果需要在初始化的时候就给成员变量赋值,我们就要重写init方法,也就是构造方法。
2、重写构造方法的时候一定要调用父类的构造方法。
3、设计构造方法的时候记得父类的属性交给父类处理。
4、构造方法必须是对象方法。