关于Objective-C中的继承

基本格式

  1. 首先准备两个类(一个父,一个子),要明白的是子类是父类中的一个特例,就好像刘德华与人类的关系,所以如果我们调用了子类就能使用父类的实例方法
#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
//这是子类的定义
  1. 观察一下上面的代码,我们的继承就发生在@interface FKApple : FKFruit这一句上(我们的Apple是一个空类)
  2. 注意点
    • 在子类的时候加上#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;
}
  1. 这样子我们可以看到输出为56,尽管我们Apple并没有weight也没有info,可我们就是可以使用

重写父类

  1. 我们可以对父类定义的方法进行修改,使之符合我们这个子类的特点
#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
  1. 注意点
    • 可以看见,我们在重写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;
}
  1. 虽然说我们改写了父类的方法,但并不是说我们把父类的方法真正改变了,在上面的例子里,如果你用的是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;
}

子类父类的成员变量不得重名

  1. 向下面这样的代码是不允许的
#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关键字(调用已经被覆盖的父类实例方法)

  1. 如题,使用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

我是太阳骑士索拉尔,愿太阳永照你心

猜你喜欢

转载自blog.csdn.net/kevinashen/article/details/80644703