利用协议模拟多继承的实现方式
- 定义协议:在Objective-C中,使用
@protocol
关键字定义协议。协议中声明方法,不提供实现。例如:
@protocol Flyable <NSObject>
- (void)fly;
@end
@protocol Swimmable <NSObject>
- (void)swim;
@end
- 类遵循协议:一个类可以遵循多个协议,通过在类的声明中列出协议名称,以
<协议1, 协议2>
这种形式。例如:
@interface Duck : NSObject <Flyable, Swimmable>
@end
@implementation Duck
- (void)fly {
NSLog(@"Duck can fly.");
}
- (void)swim {
NSLog(@"Duck can swim.");
}
@end
- 使用协议:当一个类遵循了多个协议,它就需要实现这些协议中声明的方法,从而达到类似多继承的效果,即从多个“父类”(这里用协议模拟)获取不同的行为。例如:
Duck *duck = [[Duck alloc] init];
[duck fly];
[duck swim];
实际场景及好处
- 实际场景:以游戏开发为例,假设我们有一个
Character
类,在游戏中,有些角色可以飞行(如天使),有些角色可以游泳(如美人鱼),而有些角色(如两栖飞行生物)既可以飞行又可以游泳。
- 好处
- 代码复用:如果不使用协议模拟多继承,对于可以飞行又可以游泳的角色,可能需要重复编写飞行和游泳的相关代码。而通过协议,飞行和游泳的行为可以在不同协议中定义,需要这些行为的类遵循相应协议并实现方法即可,实现代码复用。
- 灵活性:当需要新增一种行为时,只需要定义新的协议,让需要该行为的类遵循新协议并实现方法,而不需要修改大量现有类的继承结构。例如新增一个
Climbable
协议表示可攀爬,只需要让像猴子这类角色的类遵循该协议并实现攀爬方法,而不影响其他不具备攀爬能力的角色类。
- 解耦:协议使得类与类之间的依赖关系更加松散。一个类遵循某个协议,只表示它具有某种行为,而不关心其他类的具体实现细节。例如,不同类型的飞行角色(遵循
Flyable
协议),它们的飞行实现可能不同,但其他类只关心它们能飞行这一行为,而不需要了解具体飞行逻辑。