对象初始化
通过前面的学习我们已经知道两种创建对象的语法,
一种是常用的[[类名 alloc] init]语法
另一种是[类名 new]语法
这两种写法的本质是相同的
为对象分配内存空间
从前面介绍的对象的创建语法来看,无论创建哪个对象,最先总需要调用该类的alloc类方法来分配内存。
由于alloc类方法来自NSObject,而所有的Objecti-C类都是NSObject的子类,因此所有的类都可以调用alloc方法来分配内容。
当程序通过某个类的alloc类方法时,系统帮我们完成如下事情。
- 系统为该对象的所有实例变量分配内存空间。
- 每个实例变量的内存空间重置为0,具体的说,所有的整型变量所在空间都重置为0,所有的浮点型变量所在空间都重置为0.0,所有的BOOL型变量都重置为NO,所有的指针类型变量都重置为nil。
初始化方法与对象初始化
init方法同样来自NSObject,所以所有的类都可以调用该方法执行初始化。
我们可以提供自己的init方法,也就是重写NSObject的init方法。
下面是开发者重写初始化方法时,满足的模版:
- (id) init
{
//调用父类的init方法执行初始化,将初始化得到的对象赋值给self对象
//如果self不为nil,表明父类的init方法初始化成功
if(self = [super init])
{
//执行初始化……
}
return self;
}
类的继承
继承是面向对象的三大特征之一(封装,继承,多态)。
继承的特点:
OC的继承通过父类的语法实现,实现继承的类被称为子类,被继承的类称为父类,有的也称其为超类、基类。
父类与子类,就像是水果和苹果的关系,苹果继承了水果,苹果是水果的子类,苹果是一种特殊的水果。
继承的语法如下:
@interface SubClass : SuperClass
{
//成员变量定义
}
//定义方法部分
@end
子类继承得到父类的如下东西:
- 全部成员变量。
- 全部方法。
重写父类的方法
当存在子类情况特殊,需要增加父类原本没有的内容时,子类需要重写父类的方法。例如,鸟类都包含了飞翔的方法,但是鸵鸟是一种特殊的鸟类,鸵鸟不会飞,所以鸵鸟需呀重写鸟类的方法。
下面程序先定义了一个FKBird类,该类的接口部分代码如下:
#import <Foundation/Foundation.h>
@interface FKBird : NSObject
- (void) fly;
@end
下面是FKBird实现部分:
#import <Foundation/Foundation.h>
#import"FKBird.h"
@implementation FKBird
//FKBird类的fly方法
- (void) fly
{
NSLog(@"我在天空里自由自在地飞翔……");
}
@end
下面在定义一个FKOstrich类,这个类扩展了FKBird类,重写了FKBird类的fly方法。FKBird类的接口部分如下:
#import <Foundation/Foundation.h>
#import "FKBird.h"
@interface FKOstrich : FKBird
@end
从上面接口部分可以看出,当子类要重写父类方法时,子类接口部分并不需要重新声明要重写的方法,只要在类实现部分之间重写该方法即可。下面是FKOstrich类的实现部分代码:
#import <Foundation/Foundation.h>
#import "FKOstrich.h"
@implementation FKOstrich
//重写父类的fly方法
- (void) fly
{
NSLog(@“我只能在地上奔跑……");
}
@end
接下来使用如下程序测试FKOstrich类。
#import "FKOstrich.h"
int main(int argc, char * argv[])
{
@autoreleasepool{
//创建FKOstrich对象
FKOstrich* os = [[FKOstrich alloc] init];
//执行FKOstrich对象的fly方法,将输出“我只能在地上奔跑……”
[os fly];
}
}
- 执行上面的程序,将看到执行[os fly];时不再执行FKBird类的fly方法,而是执行FKOstrich类的fly方法。
- 这种子类包含与父类同名方法的现象被称为方法重写,也被称为方法覆盖。可以说,子类重写了父类的方法,也可以说子类覆盖了父类的方法。
- 方法的重写必须要注意方法签名关键字要完全相同,也就是方法名和方法签名中的形参标签都需要完全相同,否则就不能算方法重写。
super 关键字
如果需要在子类方法中调用父类被覆盖的实例方法,可使用super关键字来调用父类被覆盖的实例方法。为上面的FKOstrich类添加一个方法,在这个方法中调用FKBird被覆盖的fly方法。
- (void) callOverridedMethod
{
//在子类方法中通过super显式调用父类被覆盖的实例方法
[super fly];
}
通过callOverridedMethod方法的帮助,就可以让FKOstrich对象既可以调用自己重写的fly方法,也可以调用FKBird类中被覆盖的fly方法(调用callOverridedMethod方法即可)。
细节方面:
- super如同self不能出现在类方法中一样,super也不能出现在类方法中。类方法的调用者只能是类本身,而不是对象,因而super关键字也就失去了意义。
- 当子类继承父类时,子类可以获得父类中定义的成员变量,因此,子类接口部分不允许定义与父类接口部分重名的成员变量。