一、构造方法
1、构造方法的调用
完整的创建一个可用的对象: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。
init方法就是构造方法,是用来初始化对象的方法,注意这是一个对象方法,一减号开头。默认初始化完毕后,所有成员变量的值都为0。
2、重写构造函数
需求1:如果我需要让每个对象创建出来的初始值是10,而不是1,应该怎么办呢?
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property int age;
@end
#import "Person.h"
@implementation Person
- (instancetype)init
{
// 初始化父类中声明的一些成员变量和属性
if (self = [super init])
{
// 将_age的值初始化为10
_age = 10;
}
// 返回一个已经初始化完毕的对象
return self;
}
@end
测试程序代码:
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
// 先调用类方法,+ alloc,然后调用对象方法-init方法
// 得到Person类型对象的指针
Person *p = [[Person alloc] init];
NSLog(@"Person's age is %d", p.age);
return 0;
}
这样以后只要是通过[[Person alloc] init] 方法创建的对象的_age成员的值都是10。
需求2:让学生继承人类,要求学生对象初始化之后,年龄是10,学号是1,怎么办?
Person类的声明和实现
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property int age;
@end
#import "Person.h"
@implementation Person
- (instancetype)init
{
// 初始化父类中声明的一些成员变量和属性
if (self = [super init])
{
// 将_age的值初始化为10
_age = 10;
}
// 返回一个已经初始化完毕的对象
return self;
}
@end
Student类的声明和实现:
#import <Foundation/Foundation.h>
#import "Person.h"
@interface Student : Person
@property int no;
@end
#import "Student.h"
@implementation Student
- (instancetype)init
{
if (self = [super init]){
_no = 1;
}
return self;
}
@end
测试代码:
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"
int main(int argc, const char * argv[]) {
Student *stu = [[Student alloc] init];
NSLog(@"Student's age is %d, no is %d", stu.age, stu.no);
return 0;
}
执行结果:
2015-04-03 17:25:37.546 02-构造方法[1766:166519] Student's age is 10, no is 1
Program ended with exit code: 0
3、构造方法使用注意
(1)子类拥有的成员变量包括自己的成员变量以及从父类继承而来的成员变量,在重写构造方法的时候应该首先对从父类继承而来的成员变量先进行初始化。
(2)原则:先初始化父类的,再初始化子类的。
(3)重写构造方法的目的:为了让对象方法一创建出来,成员变量就会有一些固定的值。
(4)注意点:#1先调用父类的构造方法[super init]; #2再进行子类内部成员变量的初始化。
二、自定义构造方法
1、自定义构造方法规范
(1)一定是对象方法,所以是以-类型
(2)返回值一定是Instancetype,以前是id(我现在是使用的Xcode 6.2返回值是instancetype了类型)
(3)方法名一定是以initWith开头
2、自定义构造函数的实例:
Person类的声明:
//
// Person.h
// 03-自定义构造方法
//
// Created by rui on 4/3/15.
// Copyright (c) 2015 itcast. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property NSString *name;
@property int age;
- (instancetype)initWithName:(NSString *)name;
- (instancetype)initWithAge:(int)age;
- (instancetype)initWithName:(NSString *)name andAge:(int)age;
@end
Person类的实现:
//
// Person.m
// 03-自定义构造方法
//
// Created by rui on 4/3/15.
// Copyright (c) 2015 itcast. All rights reserved.
//
#import "Person.h"
@implementation Person
- (instancetype)init
{
if (self = [super init])
{
_name = @"Jack";
}
return self;
}
- (instancetype)initWithName:(NSString *)name{
if (self = [super init]){
_name = name;
}
return self;
}
- (instancetype)initWithAge:(int)age
{
if (self = [super init]){
_age = age;
}
return self;
}
- (instancetype)initWithName:(NSString *)name andAge:(int)age
{
if (self = [super init]){
_name = name;
_age = age;
}
return self;
}
@end
定义一个Person类的子类,Student类
它的声明:
//
// Student.h
// 03-自定义构造方法
//
// Created by rui on 4/3/15.
// Copyright (c) 2015 itcast. All rights reserved.
//
#import "Person.h"
@interface Student : Person
@property int no;
- (instancetype)initWithNo:(int)no;
- (instancetype)initWithName:(NSString *)name andAge:(int)age andNo:(int)no;
@end
Student类的实现:
//
// Student.m
// 03-自定义构造方法
//
// Created by rui on 4/3/15.
// Copyright (c) 2015 itcast. All rights reserved.
//
#import "Student.h"
@implementation Student
- (instancetype)initWithNo:(int)no
{
if (self = [super init]){
_no = no;
}
return self;
}
- (instancetype)initWithName:(NSString *)name andAge:(int)age andNo:(int)no
{
// 调用Person的initWithName:(NSString*)name andAge:(int)age方法
if (self = [super initWithName:name andAge:age]){
_no = no;
}
return self;
}
@end
测试主程序:
//
// main.m
// 03-自定义构造方法
//
// Created by rui on 4/3/15.
// Copyright (c) 2015 itcast. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"
int main(int argc, const char * argv[]) {
Person *p = [[Person alloc] init];
NSLog(@"Person's name is %@", p.name);
Person *p1 = [[Person alloc] initWithName:@"HuRui"];
NSLog(@"Perso's name is %@", p1.name);
Person *p2 = [[Person alloc] initWithAge:23];
NSLog(@"Person'a age is %d", p2.age);
Person *p3 = [[Person alloc] initWithName:@"ChenYuRong" andAge:23];
NSLog(@"Person's name is %@, age is %d", p3.name, p3.age);
Student *stu = [[Student alloc] initWithNo:137136];
Student *stu1 = [[Student alloc] initWithName:@"ChenYuRong" andAge:22 andNo:137136];
NSLog(@"%@", stu1);
NSLog(@"%@, %d, %d", stu1.name, stu1.age, stu1.no);
return 0;
}
测试结果:
2015-04-03 19:03:55.587 03-自定义构造方法[1940:192462] Person's name is Jack
2015-04-03 19:03:55.589 03-自定义构造方法[1940:192462] Perso's name is HuRui
2015-04-03 19:03:55.589 03-自定义构造方法[1940:192462] Person'a age is 23
2015-04-03 19:03:55.589 03-自定义构造方法[1940:192462] Person's name is ChenYuRong, age is 23
2015-04-03 19:03:55.590 03-自定义构造方法[1940:192462] <Student: 0x1002003e0>
2015-04-03 19:03:55.590 03-自定义构造方法[1940:192462] ChenYuRong, 22, 137136
Program ended with exit code: 0
3、自定义构造方法的使用注意
(1)自己做自己的事情(2)父类的方法交给父类的方法来处理,子类的方法处理子类自己独有的属性