MST

星途 面试题库

面试题:Objective-C Protocol的多继承模拟与冲突处理

在Objective-C中,类是单继承的,但可以通过Protocol模拟多继承。假设你有两个Protocol,ProtocolA和ProtocolB,它们都定义了一个同名但实现不同的方法 `- (void)commonMethod`。现在有一个类ClassC想要同时遵循这两个Protocol,你将如何设计以避免方法实现的冲突?请阐述详细的解决方案,并说明在实际应用场景中可能遇到的问题及应对策略。
36.9万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

解决方案

  1. 在ClassC中分别实现两个方法
    • 在ClassC类中,分别实现符合ProtocolA和ProtocolB的- (void)commonMethod方法。为了区分,我们可以在方法名上做一些变化,例如:
    @interface ClassC : NSObject <ProtocolA, ProtocolB>
    - (void)commonMethodForProtocolA;
    - (void)commonMethodForProtocolB;
    @end
    
    @implementation ClassC
    - (void)commonMethodForProtocolA {
        // ProtocolA中commonMethod的实现逻辑
    }
    - (void)commonMethodForProtocolB {
        // ProtocolB中commonMethod的实现逻辑
    }
    @end
    
    • 然后在遵循Protocol的地方进行方法转发,例如:
    @implementation ClassC <ProtocolA, ProtocolB>
    - (void)commonMethod {
        // 这里假设默认使用ProtocolA的实现
        [self commonMethodForProtocolA];
    }
    - (BOOL)respondsToSelector:(SEL)aSelector {
        if (aSelector == @selector(commonMethod)) {
            return YES;
        }
        return [super respondsToSelector:aSelector];
    }
    - (id)forwardingTargetForSelector:(SEL)aSelector {
        if (aSelector == @selector(commonMethod)) {
            // 这里可以根据一些条件选择返回实现ProtocolA或ProtocolB方法的对象
            return self;
        }
        return nil;
    }
    @end
    
  2. 使用中间类
    • 创建两个中间类,分别遵循ProtocolA和ProtocolB,并实现- (void)commonMethod
    @interface IntermediateForProtocolA : NSObject <ProtocolA>
    @end
    @implementation IntermediateForProtocolA
    - (void)commonMethod {
        // ProtocolA中commonMethod的实现逻辑
    }
    @end
    
    @interface IntermediateForProtocolB : NSObject <ProtocolB>
    @end
    @implementation IntermediateForProtocolB
    - (void)commonMethod {
        // ProtocolB中commonMethod的实现逻辑
    }
    @end
    
    • 让ClassC持有这两个中间类的实例,并在- (void)commonMethod中根据需要调用中间类的方法。
    @interface ClassC : NSObject <ProtocolA, ProtocolB>
    @property (nonatomic, strong) IntermediateForProtocolA *intermediateA;
    @property (nonatomic, strong) IntermediateForProtocolB *intermediateB;
    @end
    
    @implementation ClassC
    - (void)commonMethod {
        // 根据条件选择调用哪个中间类的方法
        [self.intermediateA commonMethod];
    }
    @end
    

实际应用场景中可能遇到的问题及应对策略

  1. 调用混淆问题
    • 问题:在使用过程中,调用者可能不清楚调用的commonMethod到底是ProtocolA还是ProtocolB的实现。
    • 策略:在文档中明确说明,并且可以在方法名上进行区分(如上述第一种解决方案),同时在代码注释中详细描述不同实现的用途。
  2. 代码复杂性增加
    • 问题:无论是通过方法转发还是使用中间类,都会增加代码的复杂性和维护成本。
    • 策略:通过良好的代码结构和注释来管理复杂性,例如将相关的中间类和逻辑封装在独立的模块中,提高代码的可读性和可维护性。
  3. 条件判断复杂
    • 问题:如果在选择不同实现时需要复杂的条件判断,可能会导致代码逻辑混乱。
    • 策略:将条件判断逻辑封装成独立的方法或函数,使其更加清晰,并且可以通过单元测试来确保条件判断的正确性。