前言
Objective-C是一门面向对象语言,是对于C语言的扩展。面向对象编程又是学习Objective-C的重中之重,但是刚入门学习时,容易被Objective-C的语法规范搞糊涂。本文尝试用倒叙的手段,由深入浅的学习Objective-C,可能更容易被读者接受,尤其是针对有着一定编程经验的读者。
@interface部分
接口(@interface)是类为对象提供特性描述。在@interface 中我们可以声明对象的数据成员、属性、以及方法。
示例:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
以上代码就是通过@interface指令为对象AllWeatherRadial声明函数以及数据成员。
@implementation部分
在@implementation中,我们用来写使得接口能够正常工作的代码。用我的话说用作实现@interface定义的方法,真正使程序能够运行在@implementation里。
注意:在@implementation中,我们不必按顺序实现接口中定义的方法,也可以在其中定义@interface本没有的方法以及数据成员。但是一旦在@implementation中声明了某个方法,那么这个方法就是当前对象的私有方法,无法被子类继承。
示例:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
我想经验丰富的读者早已看出,通过@implementation实现了对rainHandling和snowHandling两个数据成员进行get和set,读写操作的实现。
属性
刚才的代码想必太过繁琐,Objective-C 2.0中引入了属性。属性的出现使得Objective-C代码更加简洁,带来的好处是bug更少,工作效率更高。
让我们来看示例代码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
“//”是注释符号,@property命令代替了原来需要两行代码实现的声明内容。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
“//”是注释符号,@synthesize命令代替了原来冗长的实现代码。@property和@synthesize大大方便了使用者,在编译时Objective-C的机制依然会生成原先的get/set方法。
文件结构
刚才说了Objective-C类的源代码分为两部分,一部分是接口(@interface),另一部分是@implementation实现了接口所有的方法。我们将@interface放在已.h为后缀的头部文件中,同时将@implementation放在以.m为后缀的执行文件中。
以下是基本的文件构造范例:
可以清楚的看到Car,Tire,Engine,Slant6,AllWeatherRadial分别对应了一个.h以及一个.m,这里要注意main.m因为是主函数,主要是一些实现代码,因此也是以.m结尾。
另外通过Command+N快捷键命令,同样看到两种不同的Objective-C文件。
Objective-C File就是存放@implementation指令的执行文件。
Heather File就是存放@interface指令的头文件。
回到刚才的对象AllWeatherRadial,它现在被拆成AllWeatherRadial.h和AllWeatherRadial.m两个文件,其中AllWeatherRadial.m文件头部就要加上一句代码。 import "AllWeatherRadial.h"
继承与复合
继承是面向对象重要的特性,他避免了许多重复的代码。Objective-C不同于C++,它是单继承只能继承一个父类。
刚才的AllWeatherRadial他继承了Tire类,完整的代码如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Tire类通过#import引入Tire.h头文件,通过中缀符表示AllWeatherRadial继承自Tire。
复合好比是音乐中的作曲,将多个组件组合在一起使用。这里有一个Car类他同时用到了Tire和Engine两个个类,那么我们应该怎么实现呢?
Car.h文件如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
Car.m文件如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
代码中出现了NSMutableArray类,这是一个可变数组,不限制数组的长度,并且能够在数组中随意添加或删除对象,并且完成了为对象tires的定义。
添加对象操作,在该数组中添加了4个NSNull对象:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
NSMutableArray类里面有一个简便的方法replaceObjectAtIndex: withObject:,在指定的索引位置处必须存在一个能够被替换的对象。setTire:方法使用replaceObjectAtIndex: withObject:从数组集合中删除现有对象并用新对象替代。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
对象实例化
既然我们定义了类,并完成了类的实现方法,那么该如何使用它呢?这里推荐一种便捷初始化函数。
对Car类初始化代码如下:
- 1
这里嵌套调用了alloc和init两个方法,同init可以一直初始化到Car的父类,也就是NSObject类(Objective-C类中一切类的基类),而alloc则会自动管理内存,把关联的对象分配到一个相邻的内存区域内,以便于调用时消耗很少的代价,提示了程序处理速度。