Objective-C(03)|继承和方法调用(初阶)
继续书接上文,这一块的语法对于用Java的人来说,就变得友好起来了。
当然完全一样不可能的,Java的对象成员运算符“.”以及this关键字,在OC中,是由消息表达式以及self关键字体现。
初始化方法
NSObject是OC的根类,其作用与Java中的Object相似。一个类的init方法实际上是调用的NSObject类中的(id)init方法,只要类继承自NSObject类,init就一定会被调用。考虑到多层的继承关系,继承父类的初始化方法在执行时可能会出错,所以一般除非是直接继承NSObject类时,可加上结果判断:!= nil。
nil即OC中的空指针关键字。
生成实例对象的alloc方法会把实例对象的变量都初始化为0。实例变量初始化可以使用直接传参初始化,也可以先默认初始化再调用其他方法赋值。
继承的self风险点
在多重继承的时候,self关键字的使用要尤其注意。
self指的是收到当前消息的实例变量。即,如果类A中有其重写(override)的父类method_T,则执行[self method_T]时之行的是本对象的(即类A)的方法,而不是父类的。
注意和Java不同,接口和类的定义,方法名和方法不用包含进大括号,仅有实例域变量需要大括号!
The Code:
#import <Foundation/NSObject.h>
#import <stdio.h>
@interface A: NSObject
- (void)method1;
- (void)method2;
@end
@implementation A
- (void)method1
{
printf("method1 of class A.\n");
}
- (void)method2
{
printf("method2 of class A.\n");
}
@end
@interface B: A
- (void)method2; // Override
@end
@implementation B
- (void)method2
{
printf("method2 of class B.\n");
printf("self --> ");
[self method1];
printf("super --> ");
[super method2];
}
@end
@interface C: B
- (void)method1;
@end
@implementation C
- (void)method1
{
printf("method of class C.\n");
}
@end
int main(void)
{
id x = [[B alloc] init];
id y = [[C alloc] init];
printf("---instance of B---\n");
[x method1];
[x method2];
printf("---instance of C---\n");
[y method1];
[y method2];
return 0;
}
Compile:
% clang -o SelfTest selfTest.m -framework Foundation
Output:
---instance of B---
method1 of class A.
method2 of class B.
self --> method1 of class A.
super --> method2 of class A.
---instance of C---
method of class C.
method2 of class B.
self --> method of class C.
super --> method2 of class A.
局部方法
可在类的实现中添加一种供内部使用的方法,不需要在接口定义中体现,这种方法往往属于某些功能公用的方法,不在接口中定义,意味着这个方法对其他对象不可见,但是如果使用消息表达式,则仍然可以调用该方法。
没在接口中定义的局部方法,类似于没有提前声明的C语言函数,想要使用则必须定义在使用者之前。
局部方法的定义和使用,需注意继承问题,尽可能避免子类在定义时无意识对父类中局部方法的重写。Apple建议局部方法应添加固定前缀。