黑马程序员——OC—构造方法和Category

来源:互联网 发布:怎样开淘宝直播间 编辑:程序博客网 时间:2024/05/16 01:54

OC第三篇—id类型和构造方法

 

 

一、id类型:

    1. 本质:id类型是指针。

    2.作用:万能指针,能指向任何OC对象,相当于NSObject *.

    3. 使用示例:

   id p = [Person new];

 

   代码示例:

#import <Foundation/Foundation.h>
#import "Person.h"

 

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        Person *p = [Person new];
        //[p fsdfdsfd];
       
        NSObject *o = [Person new];
       
       
        // id  == NSObject *
        // 万能指针,能指向\操作任何OC对象
        id d = [Person new];
       
        [d setAge:10];
       
        [d setObj:@"321423432"];
       
        NSLog(@"%d", [d age]);
    }
    return ;

}

#import <Foundation/Foundation.h>

@interface Person : NSObject


@property int age;
@property id obj;


@end

#import "Person.h"

@implementation Person

@end

   代码分析:id类型可以指向Peson这个类型,并且操作Person的方法,和用Object的作用类似。

 

二、构造方法:

 1. 本质:方法的重写。

 2. 作用:用于初始化对象方法

 3. 创建对象的原理:

 1).分配存储空间    [类名 alloc];   调用类方法返回未初始化的对象              +alloc

 2). 初始化对象      [对象名 init];   调用对象方法进行初始化返回对象本身   -init

示例:

Person *p1 = [Person alloc];

Person *p1 = [p1 init];

合成一句后:

Person *p = [[Person alloc] init];

  

4.方法的重写:

  init是初始化,方法的重写就是重写inti方法。

示例:

- (id)init

{

    if (self = [super init])   //初始化成功,才有必要再进行初始化

    {

        _age = 10;

    }

    return self;

}

 

5. super调用:

  必要要先调用super方法,用来初始化父类中的成员变量。Object中有isa指针,因此一定要先调用super的init方法。

 

代码示例:

Person类:

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property int age;
@end

#import "Person.h"

@implementation Person


// 重写-init方法
//- (id)init
//{
//    // 1.一定要调用回super的init方法:初始化父类中声明的一些成员变量和其他属性
//    self = [super init]; // 当前对象 self
//   
//   
//    // 2.如果对象初始化成功,才有必要进行接下来的初始化
//    if (self != nil)
//    { // 初始化成功
//        _age = 10;
//    }
//   
//    // 3.返回一个已经初始化完毕的对象
//    return self;
//}

- (id)init
{
    if ( self = [super init] )
    { // 初始化成功
        _age = 10;
    }
   
    // 3.返回一个已经初始化完毕的对象
    return self;
}

@end

Student类:

#import "Person.h"

@interface Student : Person
@property int no;
@end

#import "Student.h"

@implementation Student

// 学生对象初始化完毕后,年龄就是10,学号就是1

- (id)init
{
    if ( self = [super init] )
    {
        _no = 1;
    }
    return self;
}

@end

main函数:

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"

// 构造方法:用来初始化对象的方法,是个对象方法,-开头
// 重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值
/*
 重写构造方法的注意点
1.先调用父类的构造方法([super init])
2.再进行子类内部成员变量的初始化
 */
int main()
{
    // Person *p = [Person new];
    /*
     完整地创建一个可用的对象
     1.分配存储空间  +alloc
     2.初始化 -init
     */
   
    // 1.调用+alloc分配存储空间
    // Person *p1 = [Person alloc];
    // 2.调用-init进行初始化
    // Person *p2 = [p1 init];
   
//    // 调用-init进行初始化
//    Person *p3 = [Person new];
//   
//   
//    // 每个Person对象创建出来,他的_age都是10
//   
   
    Person *p4 = [[Person alloc] init];
   
   
    Student *stu = [[Student alloc] init];
   
    NSLog(@"------");
   
    return 0;
}

 

6.自定义构造方法:

 1).方法名都以init开头

 2).返回值是id类型

 

代码示例:

- (id)initWithAge:(int)age {

    if (self = [super init]) {

        _age = age;

    }

    return self;

}

 

三、Category使用:

1. 作用:在不改变原来类的基础上,可以为类增加一些方法。

2.分类的使用格式:

分类的声明

@interface 类名 (分类名称)

// 方法声明

@end

 

分类的实现

@implementation 类名 (分类名称)

// 方法实现

@end

代码示例:

Person 类:


#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    int _age;
}
@property int age;
- (void)test;
@end

#import "Person.h"

@implementation Person

// 只有一个test方法
- (void)test
{
    NSLog(@"Person-test");
}
@end

Person+JJ 分类:

#import "Person.h"

@interface Person (JJ)
- (void)test2;
@end

 

#import "Person+JJ.h"

@implementation Person (JJ)

// 增加了一个test2方法
- (void)test2
{
    NSLog(@"-----test2");
}

// 如果在分类中定义一个和原类相同的方法,则执行分类的方法,原类不执行

- (void)test
{
    NSLog(@"Person (JJ)-test");
}
@end

 

Person+MJ 分类:

#import "Person.h"

@interface Person (MJ)
- (void)study;
@end

 

#import "Person+MJ.h"

@implementation Person (MJ)
- (void)study
{
    NSLog(@"学习-----%d", _age);
}

- (void)test
{
    NSLog(@"Person (MJ)-test");
}
@end

 

main 函数:


#import <Foundation/Foundation.h>
#import "Person.h"
#import "Person+JJ.h"

#import “Person+MJ.h”

int main()
{
    Person *p = [[Person alloc] init];
    //p.age = 10;
   
    // 优先去分类中查找,然后再去原来类中找,最后再去父类中找
    [p test];
   // [p study];
   
    return 0;
}

3.Category使用注意:

 1).  Category可以访问原始类的实例变量,但不能添加变量,只能添加方法。如果想添加变量,可以考虑通过继承创建子类

 2). Category可以实现原始类的方法,但不推荐这么做,因为它是直接替换掉原来的方法,这么做的后果是再也不能访问原来的方法

 3). Category实现中可以访问原来类中的成员变量

 4).方法调用优先级:分类(最后参与编译的分类) ->原来类 ->父类

 

4.Category的好处:

    1). 一个庞大的类可以分模块开发

    2). 一个庞大的类可以由多个人来编写,更有利于团队合作

 

 

 

0 0