美文网首页
「Objective-C」类和方法

「Objective-C」类和方法

作者: _凉风_ | 来源:发表于2016-06-23 16:34 被阅读76次

    1. 类方法和对象方法

    对象方法

    • 减号 - 开头
    • 只能由对象来调用
    • 对象方法中能访问当前对象的成员变量(实例变量)

    类方法

    • 加号 + 开头
    • 只能由类(名)来调用
    • 类方法中不能访问成员变量(实例变量)

    类方法的好处和使用场合

    • 不依赖于对象,执行效率高
    • 能用类方法,尽量用类方法
    • 场合:当方法内部不需要使用到成员变量时,就可以改为类方法

    可以允许类方法和对象方法同名

    2. self 关键字

    self 的用途

    • 谁调用了当前方法,self就代表谁
    • self出现在 对象/类 方法中,self就代表 对象/类
    • 成员变量和局部变量重名

    当成员变量和局部变量同名时,采取就近原则,访问的是局部变量
    用self访问成员变量,区分同名的局部变量

    使用细节

    • 出现的地方:所有的OC方法中(对象方法\类方法),不能出现在函数
    • 作用
      使用 "self->成员变量名" 访问当前 对象\类 方法调用的成员变量
      使用 "[self 方法名];" 来调用方法(对象方法\类方法)

    3. 继承

    好处:

    • 抽取重复代码
    • 建立类之间的关系
    • 子类可以拥有父类中 所有的 成员变量 和 方法

    坏处:增强了代码的耦合性
    重写:子类 重新实现 父类的某个方法,覆盖父类以前的方法

    使用情境:

    • A是B,则A继承B
    • A拥有B,则A组合B「即B为A内部的一个成员变量」

    super 关键字

    • 直接调用父类的 成员变量 和 对象方法
    • 使用情景:子类重写父类方法时想保留父类的一些行为

    注意

    • Objective-C 是 单继承
    • 基本上所有类的根类是NSObject
    • 不允许子类和父类拥有相同名称的成员变量
    • 父类必须声明在子类前面「实现不用在子类前」
    • 调用某个对象/类的方法时,优先去当前 对象/类 中找,若找不到去父类中找
    • 子类会继承父类所有的变量「不管是否是私有,只是能不能直接访问的问题」
    • 父类只在 implementation 里定义的变量,子类也会继承

    4. 多态「多种形态」

    定义:父类指针 指向 子类对象
    作用:若参数中使用的父类类型,则可以传入父类、子类对象
    注意

    • 编译时 编译器会检查当前类型对应的类中有没有调用方法「因为OC是弱语法」
    • 运行时 系统会动态检测对象的真实类型
    • 局限性:父类型变量不能直接调用子类的方法「可以通过强制转换来实现」

    5. 对象和对象的关系

    组合关系:类型相同 或 实现同一接口 的对象组合到一起
    依赖关系:A对象 做 B对象的 形参 或 方法的局部变量,B 依赖 A
    关联关系:A对象 做 B对象的 一个成员变量,A 和 B 有关联关系

    6. 构造方法

    完整的创建一个对象「new 方法的步骤」

    1. 调用 +alloc 方法,分配存储空间,返回一个对象 Cat *c = [Cat alloc];
    2. 调用 -init 方法,进行初始化,把成员变量的值初始化为 0,返回初始化的原来对象 c = [c init];
      [Cat new] == [[Cat alloc] init]

    目的:对象创建出来,成员变量就有一些固定的值
    方法:

    • 重写 - init 方法
    // implementation 中
    - (instancetype)init {
        // 1.调用 父类「super」 的 init 方法:初始化父类中声明的 成员变量属性 和 其他属性
        self = [super init]; // 得到当前对象 self
        if (self != nil) { // 初始化成功,nil 是空 == 0
            _min = 10; // 2. 进行子类内部成员的初始化
        }
        return self;// 返回已经初始化完毕的对象
    }
    
    • 自定义构造方法
    // implementation 中
    - (instancetype)initWithAge : (int)age {
        // 简化写法
    
        if (self = [super init]) { 
            _age = age;
        }
        return self;
    }
    

    7. 类的声明可以不写「仅仅警告」

    • 有类的声明
    // 声明
    @interface Sample : NSObject {
        // 可以有成员变量
        int a; // 默认@protected}
    
    - (void)test;
    @end
    
    // 实现
    @implementation Sample {
        // 也可以有成员变量「这种做法很少见」
        int b; // 默认 @private
        //注意:interface 和 implementation 不能声明同名的成员变量
    }
    
    - (void)test{
        NSLog(@"有类的声明");
    }
    @end
    
    • 没有类的声明「实现 必须写在main函数之前」
    // 实现
    @implementation Sample : NSObject
    - (void)test{
        NSLog(@"没有类的声明");
    }
    @end
    

    8. id 和 instancetype 数据类型

    实质:id 和 instancetype 都是 万能指针类型,能 指向/操作 任何 objc 对象
    区别:

    • id 在编译时,不能 判断对象的真实类型
      可以 定义变量,作为返回值,作为形参
    • id 不能用点语法,id可以调用任何对象的方法「这样不利于编译器检查错误」
    • instancetype 编译时,判断对象的真实类型
      只能用于返回值

    注意:自定义构造方法 返回值 尽量使用 instancetype 而不是 id
    用法:

    id  d = [Person new]; // d为指针,id 类似于 NSObject *
    NSObject *o =  [Person new];
    

    9. @class 关键字

    • 格式:@class 类名1, 类名2 「注:为了可读性,一般一个@class 对应一个类名」
    • 仅仅告诉编译器 类名 是个类,防止两个类互相调用.h文件 编译器报错
    • 开发中引用的 类规范:
      1. 在 .h 文件中用 @class 来声明
      2. 在 .m 文件中用 #import 来包含类所有的东西
    • @class 优点:
      多个头文件 #import 了同一个头文件 a时,若 a 稍有改动,则这多个头文件就都要重新编译,为了减轻编译器的负担 使用 @class

    10. 类的本质

    类对象:类本身也是个对象,是 Class 类型对象
    Class 类型定义:<code>typedef struct objc_class *Class;</code>
    为了调用类方法,获取类对象「对象的类」:<code>Class n = [对象名 class];</code> 或 <code>Class n = [类名 class];</code>

    11. 分类 Category

    作用:在不改变原来类内容的基础上,为类添加方法「继承也有这样的作用」
    好处:一个庞大的类可以分模块开发,由多人编写,更有利于团队合作
    用法:分类可以定义在 单独的 .m文件和 .h文件中,也可以定义在原来类中

    • 一般情况下,都定义在单独文件中
    • 定义在原来类中的分类,只要能看懂语法就好

    格式:

    • 在 原类名+分类名.h 文件中「文件名是规范」
    #import "原类名.h"
    @interface 类名 (分类名)
        // 方法声明;
    @end
    
    • 在 原类名+分类名.m 文件中
    #import "原类名+分类名.h"
    @implementation 类名 (分类名)
        // 方法实现
    @end;
    

    注意:

    • 分类只能增加 方法,不能增加 成员变量
    • 分类方法可以访问原来类的成员变量
    • 分类可以覆盖原来类同名的方法,会使类中原来的方法失效
    • 方法调用优先级:1.分类「最后参与编译的分类优先」→ 2.原来类 → 3.父类

    12. Class Extension 类扩展

    定义:匿名的 Category,写在 .m/.h 文件中
    作用:为某个类扩充一些私有的 成员变量 和 方法 的声明
    格式:

    #import "A.h" // 在 .m 文件中
    // 类扩展
    @interface A(){
        int _a; // 私有的成员变量 _a
    }
    - (void)sum(int) :a addWith :(int)b; // 是声明
    @end
    
    @implementation A {
        int _b;
    }
    - (void)function{
        // 实现
    }
    @end
    

    相关文章

      网友评论

          本文标题:「Objective-C」类和方法

          本文链接:https://www.haomeiwen.com/subject/qftodttx.html