分类、构造

构造方法                                                                                                        

 重写构造方法的目的:为了让对象创建出来,其成员变量就是固定值

构造方法属于对象方法

init就是构造方法,因为new方法太过于死板,只能用init来初始化,所以以后创建新对象的时候就用allocinit的方法来实现

sample code:

int main(int argc, const char * argv[])
{
    Person *p = [[Person alloc] init]; // 相当于Person *p = [Person new];
    p.age = 100;
    NSLog(@"Age is %d",p.age);
    return 0;
}


+alloc(类方法):分配存储空间

-init(对象方法):初始化

重写init                                                                                                               

int main(int argc, const char * argv[])
{
    // 要求每个Person对象被创建出来后,_age的值都是100,此时就要在.m中重写init
    Person *p = [[Person alloc] init];
    Person *p2 = [[Person alloc] init];
    NSLog(@"P Age is %d",p.age);
    NSLog(@"P2 Age is %d",p2.age);
    return 0;
}
-------------------------------------------.m文件中进行init的重写-------------------------------------------
@implementation Person
- (id)init
{
    self = [super init];// 一定要调用回super的init方法:初始化父类中声明的一些成员变量和其他属性,其实就是调用其父类中的init方法
    if (self != nil) {  // 如果不是空,说明才有初始化的必要
        _age = 100;     // 初始化_age的值
    }
    return self;        // 返回初始化好的值
}
@end

精简后的代码                                                                                                       

- (id)init
{
    if (self = [super init]) {  // 如果不是空,说明才有初始化的必要
        _age = 100;     // 初始化_age的值
    }
    return self;        // 返回初始化好的值
}

重新构造方法的注意                                                                                              

1.先调用父类的构造方法(NSOject-->父类-->子类)(super init)

2.再进行子类内部成员变量的初始化

自定义构造方法                                                                                                    

自定义构造方法的意义:将成员变量初始化

自定义构造方法的命名规范:

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

2.返回值一般是id类型

3.方法名一般以initWith开头

其定义方法和init的重新构造差不多

首先,先在.h文件中进行自定义构造方法的声明;然后再在.m文件中进行实现

例如:

.h文件:

- (id)initWithName:(NSString *)name;


.m文件:

- (id)initWithName:(NSString *)name
{
    if (self = [super init]) {
        _name = name;
    }
    return self;
}

main函数中调用:

#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[])
{
    Person *p = [[Person alloc] initWithName:@"Rose"];
    NSLog(@"%@",p.name);
     return 0;
}

自定义构造方法的注意                                                                                           

1.在子类里自定义构造方法时,如果自定义的构造方法中的变量子类没有声明,而存在于父类中,此时就要用set方法或点语法来给变量初始化值.

例如:

@implementation Student
// name,age变量是Student的父类Person类中,所以重新初始化的时候要用点语法,因为父类中的变量属于@private的
- (id)initWithNo:(int)no andName:(NSString *)name andAge:(int)age
{
    if ( self = [super init]) {
        _no = no;
        self.name = name;
        self.age = age;
    }
    return self;
}
@end


2.但其实在子类实现中用点语法或set方法初始化父类中的变量在实际写代码中不常用

可以在返回父类的init方法,然后子类再重新定义并初始化自己的变量

例如:

@implementation Student
- (id)initWithNo:(int)no andName:(NSString *)name andAge:(int)age
{        // 这样直接返回到父类的构造方法中,父类把自己的变量初始化
    if (self = [super initWithName:name andAge:age]) {
        _no = no;
    }
    return self;
}
@end

 这样写的好处是:

1>每个方法分工分明,父类方法在父类初始化,子类在子类初始化

2>如果父类中有代码改动,子类无需更改

大致思想就是,父类的属性交给父类去处理,子类的交给子类来处理

分类                                                                                            

分类的意思在于不修改原代码的前提下给某一个类扩充一些方法

格式:

// 声明
@interface 类名(分类名称) // 一般分类名称默认用模块名

@end
// 实现
@implementation 类名(分类名称)

@end

分类的好处                                                                                                           

1.如果一个类非常庞大, 需要很多种方法来实现,这个时候就可以把这些方法分类来写,每个方法写成一个类.这样就   可以把这些类分给不同的人来写,这样节省工作时间,例如团队开发中经常用到。

2.因为每个类都是单独的,所以管理和修改起来也很方便

分类使用注意                                                                                                        

1.不能扩充成员变量,只能添加方法

2.分类方法中可以访问原来类中的成员变量

3.如果重新定义分类中的方法,会把原方法覆盖掉

4.方法调用优先级:分类-->原类-->父类

5.如果两个分类中都有相同的方法,将会调用最后编译的那个分类中的方法

6.分类可以定义在单独的.h和.m文件中,也可以定义在当前类中,一般情况下都是定义在单独的文件中

给NSString添加分类                                                                                             

.h文件

#import <Foundation/Foundation.h>
 
@interface NSString (Calculate_Number)
+ (int) Calculate_NumberInString:(NSString *)str;
@end

.m文件

#import "NSString+Calculate_Number.h"
@implementation NSString (Calculate_Number)
+ (int)Calculate_NumberInString:(NSString *)str
{
    int count = 0;
    for (int i = 0; i < str.length; i++) {
         unichar c = [str characterAtIndex:i];
        if (c >= '0' && c <= '9') {
            count++;
        }
    }
    return count;
}
@end

添加对象方法:

.h文件

#import <Foundation/Foundation.h>
@interface NSString (Calculate_Number)
- (int) Calculate_Number;
@end

.m文件

- (int)Calculate_Number
{
    int count= 0;
    for (int i = 0; i < self.length; i++) {
        unichar ch = [self characterAtIndex:i];
        if (ch >='0' && ch <='9') {
            count++;
        }
    }
    return count;
}

其实可以在类方法中调用对象方法

+ (int)Calculate_NumberInString:(NSString *)str
{
      return [str Calculate_Number];
}

类的加载和初始化                                                                                                 

‍‍‍‍load方法:

在类被加载的时候,调用load方法

先加载父类的,再加载子类的

程序一启动,每个类里都要调用一遍

initialize方法:

当第一次用到这个类的时候,才会调用,也是先父类,后子类

如果有分类,优先分类


你可能感兴趣的:(分类、构造)