iOS中实现多继承

899 阅读2分钟

**1.利用组合,把需要多继承的几个对象声明成自己的几个全局变量。然狗在相应的方法中直接调用即可。
**

2.通多遵守多个协议即可,但是自己还是得提供实现。原则上来说不能算是多继承。

3.可以考虑使用分类,他不会破坏元类的分装性,优先级更高,也是Apple比较推荐的一种方式。

4.消息转发机制

具体实例:

方法1. 组合方式,用ClassC 添加ClassA ,ClassB成员变量 来调用methodA,methodB

//定义ClassA以及其methodA@interface ClassA : NSObject {}-(void)methodA;@end//定义ClassB以及其methodB@interface ClassB : NSObject {}-(void)methodB;@end//定义ClassC以及其需要的methodA,methodB@interface ClassC : NSObject {  ClassA *a;  ClassB *b;}-(id)initWithA:(ClassA *)A b:(ClassB *)B;-(void)methodA;-(void)methodB;@end//注意在ClassC的实现@implementation  ClassC-(id)initWithA:(ClassA *)A b:(ClassB *)B{       a=[[ClassA alloc] initWithClassA: A];//[A copy];b=[[ClassB alloc] initWithClassB: B];//[B copy];}-(void)methodA{[a methodA];}-(void)methodB{[b methodB];}

方法2.协议protocol 设置ClassA delegate和 ClasssB delegate 以及实现方法ClassA里的methodA,和ClasssB里的methodB。ClassC遵守这两个协议就可以。【协议支持多继承】

方法3.类别(分类)

ClassC的类别 可以实现ClassA的methodA和ClassB的methodB两个方法,这样ClassC就可以调用methodA和methodB

方法4.消息转发机制

我们知道objective-c中调用方法的方式是发消息,那如果给一个实例对象发一个未定义的消息呢?结果就是crash,其实这中间系统给我们第二次机会,就是可以转发该消息

如果未调到定义的消息,runtime会给该实例第二次机会,首先调用methodSignatureForSelector 或去方法签名,然后调用forwardInvocation,如果用户自己定义的类,没有重写这两个方法,即不支持方法转发

  •   @interface LOCBird : NSObject {      NSString* name_;  }  @end  @implementation LOCBird  - (id)init  {      self = [super init];  if (self) {  name_ = [[NSString alloc] initWithString:@"I am a Bird!!"];  
          }  return self;  }  
      - (void)dealloc  {      [name_  release];      [super dealloc];  }  
      - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector  {      NSMethodSignature* signature = [super methodSignatureForSelector:aSelector];  if (signature==nil) {          signature = [name_ methodSignatureForSelector:aSelector];      }      NSUInteger argCount = [signature numberOfArguments];  for (NSInteger i=0 ; iNSLog(@"%s" , [signature getArgumentTypeAtIndex:i]);      }  NSLog(@"returnType:%s ,returnLen:%d" , [signature methodReturnType] , [signature methodReturnLength]);  NSLog(@"signature:%@" , signature);  return signature;  }  
      - (void)forwardInvocation:(NSInvocation *)anInvocation  {  NSLog(@"forwardInvocation:%@" , anInvocation);      SEL seletor = [anInvocation selector];  if ([name_ respondsToSelector:seletor]) {          [anInvocation invokeWithTarget:name_];      }  
      }  
      @end