OC语言构造方法
一、构造方法
(一)构造方法的调用
完整的创建一个可用的对象 Person *p=[Person new];
New方法的内部会分别调用两个方法来完成2件事情:
1>使用alloc方法来分配存储空间(返回分配对象)
2>使用init方法来对对象进行初始化
可以把new方法拆开如下:
1>调用类方法+alloc分配存储空间,返回未经初始化的对象
Person *p1=[Person alloc];
2>使用对象方法-init进行初始化,返回对象本身
Person *p2=[p1 init];
3>以上两个过程合二为一
Person *p=[[Person alloc] init];
说明:init方法就是构造方法,用来初始化对象的方法,注意这是一个对象方法,以-开头,默认初始化完成以后所有的成员变量值均为0.
(二)构造方法的代码示例
1>如果我们需要让每个对象创建出来的初始值是10,而不是1,如何操作呢?
Person类的声明
#import <Foundation/Foundation.h> @interface Person : NSObject /** 年龄*/ @property NSInteger age; @end
Person类的实现
#import "Person.h" @implementation Person #pragma mark - 重写init方法 -(instancetype)init{ //初始化对象拥有的父类成员变量 self=[super init]; if (self) { //初始化对象自有的成员变量 _age=10; } //返回一个已经初始化完成的对象 return self; } @end
调用
#import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { //初始化 Person *p=[[Person alloc] init]; //输出调用 NSLog(@"%ld",p.age); } return 0; }
2>创建一个人类,要求创建出来的所有学生类的年龄初始值为10,学号为0
分析:学生类继承人类,同样能继承人类的init重写
Person类的声明
#import <Foundation/Foundation.h> @interface Person : NSObject /** 年龄*/ @property NSInteger age; @end
Person类的实现
#import "Person.h" @implementation Person #pragma mark - 重写init方法 -(instancetype)init{ //初始化对象拥有的父类成员变量 self=[super init]; if (self) { //初始化对象自有的成员变量 _age=10; } //返回一个已经初始化完成的对象 return self; } @end
Student类的声明
#import "Person.h" @interface Student : Person /** 学号*/ @property NSInteger no; @end
Student类的实现
#import "Student.h" @implementation Student #pragma mark - 重写init方法 -(instancetype)init{ //初始化对象拥有Person类的成员变量 self=[super init]; if (self) { //初始化对象自有的成员变量 _no=0; } //返回一个已经初始完的对象 return self; } @end
调用
#import <Foundation/Foundation.h> #import "Person.h" #import "Student.h" int main(int argc, const char * argv[]) { @autoreleasepool { //初始化 Person *p=[[Person alloc] init]; Student *s=[Student new]; //输出调用 NSLog(@"%ld",p.age); NSLog(@"%ld",s.no); } return 0; }
(三)构造方法的使用注意
1>子类拥有的成员变量包括自己的成员变量以及从父类继承而来的成员变量,在重写构造方法的时候应该首先对从父类继承而来的成员变量先进行初始化。
2>原则:先初始化父类的,再初始化子类的。
3>重写构造方法的目的:为了让对象方法一创建出来,成员变量就会有一些固定的值.
4>注意点:先调用父类的构造方法[super init],再进行子类内部成员变量的初始化.
二、自定义构造方法
(一)自定义构造方法的规范
1>一定是对象方法,以-开头
2>返回值一般是instance类型
3>方法名一般以initWith开头
(二)自定义构造方法的代码实现示例
Person类的声明,其中声明了两个接收参数的自定义构造方法
#import <Foundation/Foundation.h> @interface Person : NSObject /** 姓名*/ @property NSString *name; /** 学号*/ @property NSInteger no; /** * 自定义构造方法 * * @param name 姓名 * * @return */ -(instancetype)initWithName:(NSString *)name; /** * 自定义构造方法 * * @param name 姓名 * @param no 学号 * * @return */ -(instancetype)initWithName:(NSString *)name andNo:(NSInteger)no; @end
Person类的实现
#import "Person.h" @implementation Person #pragma mark - 自定义一个接收一个参数的构造方法 -(instancetype)initWithName:(NSString *)name{ //初始化对象拥有父类成员变量 self=[super init]; if(self){ _name=name; } return self; } #pragma mark - 自定义一个接收两个参数构造方法 -(instancetype)initWithName:(NSString *)name andNo:(NSInteger)no{ self=[super init]; if(self){ _name=name; _no=no; } return self; } @end
Student类的声明,声明了一个接收三个参数的构造方法
#import "Person.h" @interface Student : Person /** 年龄*/ @property NSInteger age; /** * 自定义构造方法 * * @param name 姓名 * @param no 学号 * @param age 年龄 * * @return */ -(instancetype)initWithName:(NSString *)name andNo:(NSInteger)no andAge:(NSInteger)age; @end
Student类的实现
#import "Student.h" @implementation Student #pragma mark - 自定义一个接收三个参数的构造方法 -(instancetype)initWithName:(NSString *)name andNo:(NSInteger)no andAge:(NSInteger)age{ //调用父类的构造方法初始化两个变量 self=[super initWithName:name andNo:no]; if (self) { //初始化自己独有的成员变量 _age=age; } return self; } @end
主程序测试
#import <Foundation/Foundation.h> #import "Person.h" #import "Student.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *p1=[[Person alloc] initWithName:@"zhangsan"]; NSLog(@"%@",p1.name); Person *p2=[[Person alloc] initWithName:@"zhangsan" andNo:1001]; NSLog(@"%@ %ld",p2.name,p2.no); Student *stu=[[Student alloc] initWithName:@"zhangsan" andNo:1001 andAge:10]; NSLog(@"%@ %ld %ld",stu.name,stu.no,stu.age); } return 0; }
(三)自定义构造方法注意点
1>自己做自己的事情
2>父类的方法交给父类的方法来处理,子类的方法处理子类自己独有的属性