美文网首页技术栈
iOS 实现多继承的几种方式

iOS 实现多继承的几种方式

作者: 学不来的凡人 | 来源:发表于2021-03-21 07:25 被阅读0次

我们都知道OC是不支持多继承的,这是因为消息机制名称查找发生在运行时而非编译时,很难解决多个基类可能导致的二义性问题,那么如果我们想要一个类a同时继承类b和类c,我们要如何做才能达到我们想要的结果呢?我们创建三个类ClassA、ClassB、ClassC,A和B分别有两个方法run和walk,假设我们需要让C同时拥有run和walk方法,我们可以通过下面几种方法来达到我们想要的效果。

1、组合

Son添加两个属性father1(- (void)playFootBall),father2(- (void)playBasketball)。那么Son就有了father1和father2的能力。类似于继承了他们两个!!!

@class Father1,Father2;
@interface Father1 : NSObject
- (void)playFootBall;
@end

@interface Father2 : NSObject
- (void)playBasketball;
@end

@interface Son : NSObject
@property (nonatomic,strong)Father1 *father1;
@property (nonatomic,strong)Father2 *father2;
- (void)playBall;

@end
#import "Son.h"
@implementation Father1
- (void)playFootBall{
    NSLog(@"playFootBall");
}
@end
@implementation Father2
- (void)playBasketball{
    NSLog(@"playBasketball");
}
@end

@implementation Son
- (instancetype)init{
    if (self = [super init]) {
        self.father1 = [Father1 new];
        self.father2 = [Father2 new];
    }
    return self;
}
- (void)playBall{
    [self.father1 playFootBall];
    [self.father2 playBasketball];
    
}
@end

2、delegate和protocol

将C类需要继承的方法以及属性在A和B中各自声明一份协议,C类遵守这两份协议,同时在C类中实现协议中的方法以及属性

@protocol ADelegate
@property (nonatomic,copy)NSString *jinqiu;
- (void)playFootBall;
@end

@protocol BDelegate
@property (nonatomic,copy)NSString *defen;
- (void)playBasketball;
@end

@interface C : NSObject
- (void)playBall;
@end
#import "C.h"
@interface C()<ADelegate,BDelegate>

@end
@implementation C
- (void)playBall{
    [self playFootBall];
    [self playBasketball];
}
- (void)playFootBall{
    self.jinqiu = @"3个进球";
    NSLog(self.jinqiu);
    
}
- (void)playBasketball{
    self.defen = @"得了30分";
    NSLog(self.defen);

}

@synthesize jinqiu;

@synthesize defen;

@end

3、消息转发(1、快速转发和2、标准转发)

@class Dog;
@interface Dog : NSObject
- (void)eatShi;
@end
@interface Cat : NSObject

- (void)eatFish;

@end
#import "Cat.h"
@implementation Dog
- (void)eatShi{
    NSLog(@"吃屎");
}
@end
@implementation Cat
- (void)eatFish{
    NSLog(@"吃鱼");
}
//1、快速转发(有快速转发走快速转发)
- (id)forwardingTargetForSelector:(SEL)aSelector{
    Dog *dog = [Dog new];
    return dog;
}
//2、(没有快速转发走标准消息转发)
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
   Dog *dog = [Dog new];
    
   NSMethodSignature *signature = [dog methodSignatureForSelector:aSelector];
   return  signature;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation{
   SEL selector = [anInvocation selector];
    Dog *dog = [Dog new];
   if([dog respondsToSelector:selector]){
       [anInvocation invokeWithTarget:dog];
   }
}
@end
    [((Dog*)[Cat new]) eatShi];
2021-03-19 16:37:14.053339+0800 IOS--多继承[79529:1773692] 吃屎

4、类别(category)

类别也可以用来模拟多继承,比如给当前类添加方法,利用runTime来添加属性,方法不表,别人文章Category与Extension有实现,可以参考

5、NSProxy

NSProxy 并没有继承NSObject ,而是实现了NSObject协议
NSProxy 和 NSObject 类都实现了NSObject 协议 ,我们仔细看发现NSProxy并没有init或new方法 ;这个就尴尬了,这个类是一个魏忠贤版的类。。。。。init方法貌似需要子类去实现,也就是这个类注定要被别的类继承。
实现与3、消息转发(1、快速转发和2、标准转发)一样,只不过3、消息转发是继承NSObject ,而现在是使用NSProxy和NSObject有共同的协议,创建NSProxy的子类进行消息转发
结论: 如此看来NSProxy确实更适合实现做为消息转发的代理类, 因为作为一个抽象类, NSProxy自身能够处理的方法极小(仅<NSObject>接口中定义的部分方法), 所以其它方法都能够按照设计的预期被转发到被代理的对象中.而NSObject很多方法自己有实现,例如respondsToSelector:和isKindOfClass,这样的话就不会走消息转发流程。(消息转发是只有当接收者无法处理时才会通过forwardInvocation:来寻求能够处理的对象.)
总结:NSProxy比NSObject更干净。
注意:NSProxy这个基类没有定义默认的init方法.

NSProxy类


image.png

相关文章

  • category与extension

    category与extension 转载iOS实现多继承的几种方式 转载

  • iOS实现多继承的几种方式

    背景 我们都知道OC是不支持多继承的,这是因为消息机制名称查找发生在运行时而非编译时,很难解决多个基类可能导致的二...

  • iOS 实现多继承的几种方式

    我们都知道OC是不支持多继承的,这是因为消息机制名称查找发生在运行时而非编译时,很难解决多个基类可能导致的二义性问...

  • iOS 中几种多继承的实现方式

    单继承与多继承概念 继承是面向对象的基本特征之一,在具体语言的语法上设计有两种形式:多继承与单继承。 单继承 一个...

  • iOS 多继承实现方式

    一、单继承与多继承概念 继承是面向对象的基本特征之一,在具体语言的语法上设计有两种形式:多继承与单继承。 1.单继...

  • iOS开发之UITableView中计时器的几种实现方式

    iOS开发之UITableView中计时器的几种实现方式 iOS开发之UITableView中计时器的几种实现方式

  • java多线程常见面试题

    1.java多线程有哪几种实现方式 三种方式: 1.继承Thread类实现多线成 2.实现Runnable接口 3...

  • 2021-01-26

    实现多线程的方式到底有几种?1.如何创建多线程方式一:继承Thread类方式二:实现Runnable接口继承Thr...

  • JavaScript中继承的实现方式---笔记

    继承的几种实现方式:原型链、借用构造函数、组合继承、原型式继承、寄生式继承、寄生组合式继承;继承的实现,一般有接口...

  • 实现线程的方式,源码分析:Runnable, Thread, C

    前言 在 Java 中,实现线程的方式主要有以下几种方式:继承 Thread, 实现 Runnable 和实现 C...

网友评论

    本文标题:iOS 实现多继承的几种方式

    本文链接:https://www.haomeiwen.com/subject/zvavcltx.html