基本格式
- 首先准备两个类(一个父,一个子),要明白的是子类是父类中的一个特例,就好像刘德华与人类的关系,所以如果我们调用了子类就能使用父类的实例方法
#import <Foundation/Foundation.h>
@interface FKFruit : NSObject
@property (nonatomic , assign) double weight;
- (void) info;
@end
//这是父类的定义
#import "FKFruit.h"
@implementation FKFruit
@synthesize weight;
- (void) info {
NSLog(@"我是一个水果!重%gg! " , weight);
}
@end
//这是父类的实现
#import <Foundation/Foundation.h>
#import "FKFruit.h"
@interface FKApple : FKFruit
@end
//这是子类的定义
- 观察一下上面的代码,我们的继承就发生在@interface FKApple : FKFruit这一句上(我们的Apple是一个空类)
- 注意点
- 在子类的时候加上#import “FKFruit.h”
- 在主函数调用的时候要记清楚主类父类的关系,我们所import得一定是子类
#import <Foundation/Foundation.h>
#import "FKApple.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建FKApple对象
FKApple* a = [[FKApple alloc] init];
//FKApple对象本身没有weight属性
//因为FKApple的父类有weight属性,也可以访问Apple对象的weight属性
a.weight = 56;
//调用FKApple对象的info方法
[a info];
}
return 0;
}
- 这样子我们可以看到输出为56,尽管我们Apple并没有weight也没有info,可我们就是可以使用
重写父类
- 我们可以对父类定义的方法进行修改,使之符合我们这个子类的特点
#import <Foundation/Foundation.h>
@interface FKBird : NSObject
- (void) fly;
@end
#import "FKBird.h"
@implementation FKBird
//FKBird类的fly方法
- (void) fly {
NSLog(@"我在天空里自由自在地飞翔。。。");
}
@end
#import <Foundation/Foundation.h>
#import "FKBird.h"
@interface FKOstrich : FKBird
@end
#import "FKOstrich.h"
@implementation FKOstrich
//
- (void) fly {
NSLog(@"我只能在地上奔跑。。。");
}
@end
- 注意点
- 可以看见,我们在重写fly方法的时候没有再次定义,而是直接重写了。当然,重新定义fly不会导致任何错误
#import <Foundation/Foundation.h>
#import "FKOstrich.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建FKOstrich
FKOstrich* os = [[FKOstrich alloc] init];
//执行FKOstrish对象的fly方法,将输出“我只能在地上奔跑。。。”
[os fly];
}
return 0;
}
- 虽然说我们改写了父类的方法,但并不是说我们把父类的方法真正改变了,在上面的例子里,如果你用的是FKBird来定义(头文件还是用Os,这也说明了不止方法,对于父类中的类我们也可以直接拿来用),输出的还是飞行,不会改变
#import <Foundation/Foundation.h>
#import "FKOstrich.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建FKOstrich
FKBird* os = [[FKBird alloc] init];
//执行FKOstrish对象的fly方法,将输出“我只能在地上奔跑。。。”
[os fly];
}
return 0;
}
子类父类的成员变量不得重名
- 向下面这样的代码是不允许的
#import <Foundation/Foundation.h>
@interface FKBase : NSObject
{
@private
int _a;
}
@end
#import <Foundation/Foundation.h>
#import "FKBase.h"
@interface FKSubclass : FKBase
{
int _a;
}
@end
上面的代码中我们已经使用private限制符来使他只能在一个类中被调用,依然不行,应该说是一条难以逾越的红线了
super关键字(调用已经被覆盖的父类实例方法)
- 如题,使用super关键字可以找回被覆盖的实例方法
#import <Foundation/Foundation.h>
@interface FKParent : NSObject
{
int _a;
}
@property (nonatomic , assign) int a;
@end
#import "FKParent.h"
@implementation FKParent
@synthesize a = _a;
- (instancetype) init {
if (self = [super init]) {
self->_a = 5;
}
return self;
}
@end
#import <Foundation/Foundation.h>
#import "FKParent.h"
@interface FKSub : FKParent
- (void) accessOwner;
@end
#import "FKSub.h"
@implementation FKSub
{
//该成员变量将会隐藏父类的成员变量
int _a;
}
- (instancetype) init
{
if (self = [super init]) {
self->_a = 7;
}
return self;
}
- (void)accessOwner
{
//直接访问得是当前类中的成员变量
NSLog(@"子类中的_a成员变量:%d" , _a);
//访问父类中被隐藏的成员变量
NSLog(@"父类中被隐藏的_a成员变量:%d" , super.a);
}
@end
#import <Foundation/Foundation.h>
#import "FKSub.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
FKSub* sub = [[FKSub alloc] init];
[sub accessOwner];
}
return 0;
}
这里要记住初始化得那个格式,使用super init