iOS 多继承四种实现方式

参考博客

协议和 NSProxy 实现多继承


多继承可以允许子类从多个父类派生,而Objective-C并不支持多继承,但我们仍可间接实现。
Objective-C实现多继承主要可以通过协议、分类、消息转发来实现。我们来总结一下其使用以及优缺点。

1. 组合方式实现

person类继承与singer和dancer类,则可以让person继承与singer,然后实例化一个dancer的对象,就可以即调用singer又可以调用dancer的方法。

外部调用时就是[person.dancer 方法名]

2. 通过协议实现

协议只能提供接口,不能提供实现,所以要在子类中添加想应的实现。(我感觉只是让方法更加模块化,更加清晰,实现还是写在当前类)

3. 通过分类和三次拯救中的第二次拯救

在外部调用可以是[person 方法名]

把方法名写在分类中,外部就可以直接以person的对象调用方法而不报错,此时只是外部可以调用而不报错,但并没有方法的实现。
在三次拯救的第二次拯救(备用接收者)中,把该方法的实现转交给dance类,这样[perosn dance]也可以实现dancer类的dance方法。

4. 协议和NSProxy实现

主要是让当前类转变为singer或者dancer。

现在再说 NSProxy, 这才是真的代理

NSProxy:

测试demo
这个类是和 NSObject 平起平坐的, 而且这个类没有 init 方法,也就是说,它只可以开辟一块内存空间,而不能初始化. 那么,我怎么样这个类可以变成任意一个类呢?

主要有这样几步,

  • 我先设置一个类 PYRProxy, 继承自 NSProxy
  • 为 YFProxy 设置一个 NSObject 属性
  • 自定义一个转换方法,相当于给 NSObject 属性赋值
  • 然后通过这个属性获得调用方法的方法签名
  • 为调用设置目标
  • 调用

详见协议和 NSProxy 实现多继承
里面步骤比较清楚。

  1. 一个继承自NSProxy的PYRProxy类,用于在类中自由转换
    .h文件
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface PYRProxy : NSProxy

@property (nonatomic, strong)NSObject *object;
- (id)transformToObject:(NSObject *)obj;

@end

NS_ASSUME_NONNULL_END

.m文件

#import "PYRProxy.h"

@implementation PYRProxy

- (id)transformToObject:(NSObject *)obj {
    self.object = obj;
    return self.object;
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
    NSMethodSignature *methodSignature;
    if (self.object) {
        methodSignature = [self.object methodSignatureForSelector:sel];
    } else {
        methodSignature = [super methodSignatureForSelector:sel];
    }
    return methodSignature;
}

- (void)forwardInvocation:(NSInvocation *)invocation {
    if (self.object) {
        [invocation setTarget:self.object];
        [invocation invoke];
    }
}

@end

  1. 外部调用
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    Person *person = [[Person alloc] init];
    Animal *animal = [[Animal alloc] init];
    PYRProxy *proxy = [PYRProxy alloc];
    [proxy transformToObject:person];
    [proxy performSelector:@selector(personSay)];
    [proxy transformToObject:animal];
    [proxy performSelector:@selector(animalSay)];
}


@end

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值