OC学习笔记之OC类自定义构造方法

 

    
一、构造方法续:自定义构造
        上一篇笔记小桥讲到了OC类的构造方法,这里先复习一下,下面是一个Person类,有姓名和年龄两个成员变量:

//
//  文件:Person.h
//  项目:博客笔记
//  作者:葬花 桥
//  日期:14-5-7
//  版权:Copyright (c) 2014年 itcast. All rights reserved.
//
#import 

@interface Person :NSObject

@propertyNSString *name;//姓名
@property int age;//年龄

@end 

//
//  文件:Person.m
//  项目:博客笔记
//  作者:葬花 桥
//  日期:14-5-7
//  版权:Copyright (c) 2014年 itcast. All rights reserved.
//
#import "Person.h"

@implementation Person

// 重写init默认构造方法
- (id)init
{
   if (self = [superinit])
    {
       _name =@"桥";
    }
    return self;
}

@end 

    当我们在main函数中实例一个Person对象时,对象的姓名就被初始化成了 @"桥",当然,年龄还是0,因为小桥没有对年龄初始化。下面看一下测试:
 
 
  
    这是重写NSObject的init构造方法,我们经常需要初始化的值为外部传进来的值,而不是在构造方法中写死的值,毕竟Person实例的对象不可能全部都叫@"桥"。自定义构造方法MJ老师说的规范小桥这里摘抄一下:

/*

 自定义构造方法的规范

 1.一定是对象方法,一定以 -开头

 2.返回值一般是id类型

 3.方法名一般以initWith开头

*/

1.因为是在实例对象的时候初始化对象,所以是对象方法
2.id类型可以指向任何OC对象
3.方法名以initWith开头可读性强,接触过cocos2d-x的读者可能会看到虽然可以用C++写,但是它低版本的API带有这种风格。
4.还有一点要注意,自定义构造方法要在类声明部分声明,因为它不是父类方法,所以不是重写,而是我们自己写的方法。
    下面小桥写几个自定义构造方法,可以根据外部参数初始化成员: 

//  文件:Person.h
//  项目:博客笔记
//  作者:葬花 桥
//  日期:14-5-7
//  版权:Copyright (c) 2014年 itcast. All rights reserved.
//
#import 

@interface Person :NSObject

@propertyNSString *name;//姓名
@property int age;//年龄

// 自定义构造方法初始化姓名
- (id)initWithName:(NSString *)name;
// 自定义构造方法初始化年龄
- (id)initWithAge:(int)age;
// 自定义构造方法同时初始化姓名和年龄
- (id)initWithName:(NSString *) name andAge:(int)age;

@end      

//  文件:Person.m
//  项目:博客笔记
//
//  作者:葬花 桥
//  日期:14-5-7
//  版权:Copyright (c) 2014年 itcast. All rights reserved.
//
#import "Person.h"

@implementation Person

// 重写init默认构造方法
- (id)init
{
   if (self = [superinit])
    {
       _name =@"桥";
    }
    return self;
}

// 自定义构造方法初始化姓名
- (id)initWithName:(NSString *)name
{
   if (self = [superinit])
    {
       _name = name;
    }
    return self;
}
 
// 自定义构造方法初始化年龄
- (id)initWithAge:(int)age
{
   if (self = [superinit])
    {
       _age = age;
    }
    return  self;
}
 
// 自定义构造方法同时初始化姓名和年龄
- (id)initWithName:(NSString *) name andAge:(int)age
{
   if (self = [superinit])
    {
       _name = name;
       _age = age;
    }
    return self;
}

@end


    读者可能看出来了,自定义构造方法一般都是带参数的,因为我们要根据传的参数来初始化成员变量,而不是写死,这样我们就可以灵活地实例出想要的对象了,下面再来测试一下:
 

  
        可以看到,我们想要怎么去初始化我们的成员变量,在实例对象的时候就调用对应的自定义构造方法,这样,在外面就不必调用set方法去作赋值这一多余的操作。在这里小桥再写一个我认为比较简洁的写法,读者可以自己比较一下差别:

//
//  文件:Person.m
//  项目:博客笔记
//
//  作者:葬花 桥
//  日期:14-5-7
//  版权:Copyright (c) 2014年 itcast. All rights reserved.
//
#import "Person.h"

@implementation Person

// 重写init默认构造方法
- (id)init
{
   if (self = [superinit])
    {
       _name =@"桥";
    }
    return self;
}

// 自定义构造方法初始化姓名简洁写法
- (id)initWithName:(NSString *)name
{
   if (self = [selfinitWithName:nameandAge:0])
    {
        //_name = name;
    }
    return self;
}
// 自定义构造方法初始化年龄简洁写法
- (id)initWithAge:(int)age
{
   if (self = [selfinitWithName:0andAge:age])
    {
        //_age = age;
    }
    return  self;
}
// 自定义构造方法同时初始化姓名和年龄
- (id)initWithName:(NSString *) name andAge:(int)age
{
   if (self = [superinit])
    {
       _name = name;
       _age = age;
    }
    return self;
}

@end       

         
二、[super init]
          不管是默认的构造方法init还是自定义的构造方法,它们的方法体结构都是相似的。一行条件语句和一行返回语句,返回语句返回的是对象地址,重点说下条件语句中的 
[super init] ; 小桥在前面的笔记中可能提到过(也可能没有,小桥记性太差了 -_-)super指针,和self指针相似的功能,但是它是与父类相关联的。这里就是调用父类的init方法,也就是父类的默认构造方法,当一个对象创建的时候,要初始化它,总是先初始化它父类的成员,C++中也是这样,OC中总是有父类的,即使是根类NSObject也有成员isa。小桥新建一个Student类作为Person的子类来具体说明下。

//  文件:Student.h
//  项目:博客笔记
//  作者:葬花 桥
//  日期:14-5-7
//  版权:  Copyright (c) 2014年 itcast. All rights reserved.
//
#import "Person.h"

@interface Student :Person

@propertyNSString *studentID;// 学号

// 初始化姓名、年龄、学号
- (id)initWithName:(NSString *)name andAge:(int)age andStudentID:(NSString *)studentID;

@end

//  文件:Student.m
//  项目:博客笔记
//  作者:葬花 桥
//  日期:14-5-7
//  版权:Copyright (c) 2014年 itcast. All rights reserved.
//
#import "Student.h"

@implementation Student

// 同时初始化姓名、年龄、和学号
- (id)initWithName:(NSString *)name andAge:(int)age andStudentID:(NSString *)studentID
{
   if (self = [superinitWithName:nameandAge:age]) //调用父类构造方法
    {
       _studentID = studentID; 
    }
    return self;
}
@end 

        在Student类小桥写了一个自定义构造方法,初始化姓名、年龄和学号,注意,实现中的父类构造方法调用,这里用父类的自定义构造方法初始化了姓名和年龄,如果调用的是父类的默认构造方法,那么这两个成员初始化就是0了,Student类的默认构造方法就是这么做的。请注意测试函数test3() 中的两个对象初始化的不同之处
               
 

     本笔记就写到这里,下一笔记小桥要复习一下category 分类的知识




你可能感兴趣的:(学习笔记)