「Objective-C」类和方法

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容