继承的特点
定义
子类:实现继承的叫子类
父类:被继承的叫父类
举个例子:
水果和苹果的关系,苹果继承了水果,苹果是水果的子类;而水果就是苹果的父类。
语法格式
@interface SubClass:SuperClass
{
//成员变量定义
}
//方法定义
@end
定义子类的语法非常简单,只需在原来的类定义上增加 “:SuperClass” 即可。
当子类继承 父类时,子类可以继承得到父类的如下东西:
- 全部成员变量
- 全部方法
父类数量与子类数量的关系
OC类只能有一个直接父类,但是可以有无限多个间接父类。
例如:
@interface FKFruit : FKPlant {
...} @end
@interface FKApple : FKFruit {
...} @end
上面类定义中,FKFuit 是FKApple的父类,FKPlant类也是FKApple类的父类。区别是:FKFruit 是 FKApple 的直接父类,而FKPlant是FKApple 的间接父类。
下面的代码示范了子类继承父类的特点:
FKFruit.h
#import <Foundation/Foundation.h>
@interface FKFruit : NSObject
@property (nonatomic, assign) double weight;
-(void) info;
@end
FKFruit.m
#import "FKFruit.h"
@implementation FKFruit
@synthesize weight;
-(void) info{
NSLog(@"我是一个水果!重%gg!", weight);
}
@end
FKApple.h
#import <Foundation/Foundation.h>
#import "FKFruit.h"
@interface FKApple :FKFruit
@end
主函数:
#import <Foundation/Foundation.h>
#import "FKApple.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建FKApple的对象
FKApple* a = [[FKApple alloc] init];
//FKApple对象d本身没有weight属性
//因为FKApple的父类有weight属性,也可以访问Apple对象的weight的属性
a.weight = 56;
[a info];
}
return 0;
}
效果展示
重写父类的方法
大部分时候,子类总是以父类为基础,额外增加新的Field和方法。但有一种情况例外:子类需要重写父类的方法。
代码演示
FKBird.h
#import <Foundation/Foundation.h>
@interface FKBird : NSObject
-(void) fly;
@end
从上面接口部分可以看出,当子类要重写父类方法时,子类接口并不需要重新声明要重写的方法,只要在类实现部分直接重写该方法即可。
FKBird.m
#import<Foundation/Foundation.h>
#import "FKBird.h"
@implementation FKBird
//FKBird类的方法fly方法
-(void)fly
{
NSLog(@"我在天空里自由自在地飞翔...");
}
@end
FKOstrich.h
#import <Foundation/Foundation.h>
#import "FKBird.h"
@interface FKOstrich : FKBird
@end
FKOstrich.m
#import "FKOstrich.h"
@implementation FKOstrich
-(void) fly
{
NSLog(@"我只能在地上奔跑...");
}
@end
效果展示:
这种子类包含于父类同名方法的现象被称为方法重写,也被称为方法覆盖。可以说:子类重写了父类的方法,也可以说子类覆盖了父类的方法。
注:方法的重写必须注意方法签名关键字要完全相同,也就是方法名和方法标签中的形参标签都需要完全相同,否则不能算方法重写。
super关键字
调用被子类覆盖的父类方法
示例:
FKBird.h 和 FKBird.m 不变;
FKOstrich.h
#import <Foundation/Foundation.h>
#import "FKBird.h"
@interface FKOstrich : FKBird
-(void) callOverridedMethod;
@end
FKOstrich.m
#import "FKOstrich.h"
@implementation FKOstrich
-(void) fly
{
NSLog(@"我只能在地上奔跑...");
}
-(void) callOverridedMethod {
[super fly];
}
@end
**
**
从上面代码可以看出:
super用于限定该对象调用它从父类继承得到的属性和方法。
几点说明
- 正如self不能出现在类方法中一样,super也不能出现在类方法中。类方法的调用者只能是类本身,而不是对象,因而super关键字也就失去了意义。
- 无论父类接口部分的成员变量使用何种访问控制符限制,当子类继承父类时,子类可以获得父类中定义的成员变量,因此子类接口部分不允许定义与父类接口部分重名的成员变量。
- 无论是接口部分还是实现部分定义的成员变量,子类都完全可以与父类实现部分定义的成员变量同名。
- 程序通过super关键字强制指定调用父类的中被隐藏的属性(实际上就是获取getter方法的返回值),通过这种方式可以访问到父类中被隐藏的成员变量。