在Objective C中实现相同协议的类之间共享公共方法实现

时间:2010-07-16 05:18:14

标签: objective-c

我有一个协议。

MyProtocol.h:

@protocol MyProtocol
  @property(nonatomic, retain) NSString* someString;
  - (void)doesSomethingWithSomeString;
@end

实现相同协议的2个类。由于某种原因,这两个类不能从同一个基类继承。例如。其中1个可能需要从NSManagedObject(Apple的Cocoa框架中的Core Data类)继承而另一个不应该继承。

Class1.h:

@interface Class1: NSObject<MyProtocol> {
  NSString* someString;
}

//Some method declarations

@end

Class1.m

@implementation Class1
  @synthesize someString;

  - (void)doesSomethingWithSomeString {
    //don't use property here to focus on topic
    return [[self someString] capitalizedString];
  }

  //Method definitions for methods declared in Class1
@end

Class2.h:

@interface Class2: SomeOtherClass<MyProtocol> {
  NSString* someString;
}

//Some method declarations

@end

Class2.m

@implementation Class2
  @synthesize someString;

  // This is exactly the same as -doesSomethingWithSomeString in Class1.
  - (void)doesSomethingWithSomeString {
    //don't use property here to focus on topic
    return [[self someString] capitalizedString];
  }

  //Method definitions for methods declared in Class2
@end

如何避免重复-doesSomethingWithSomeString? (我想我需要类似多类的类别)。

更新

有一些帮助类的建议,并将来自Class1和Class2的调用委托给它。这通常是一种很好的方法,特别是如果方法很长的话。

在这种情况下,我正在查看从NSObject继承的Class1和继承自NSManagedObject的Class2。后者是Class2必须从中继承的基类,作为Apple Core Data框架中的模型/实体。

因此,虽然委托第三类是一种方法,但需要有很多样板委托包装代码,这些代码相当于第三类中的许多短1-2方法。即高样板代理代码到实际代码比例。

另一点是,由于这是一个模型类,公共代码主要作用于ivars / properties,委托类最终会像全局C函数一样编写。

3 个答案:

答案 0 :(得分:2)

您可以创建一个辅助类,然后在Class1和Class2中使用它,然后只复制对辅助类的方法的重复

答案 1 :(得分:2)

这种情况表明您的Class1Class2没有完全考虑到只处理一个问题的类中。您有一个共同的实现这一事实表明应该有第三个类提供该实现,Class1Class2可以委托该关注。换句话说,这是组合而不是继承的情况。

更新 如果委托给一个类是没有意义的,不要忘记Objective-C是C的超集。没有什么可以阻止你实现一个C函数库,你可以从这两个类中调用它来封装常见的行为。如果您致力于NSAssert 等等等便利,您可以始终在NSObject上的实用程序类或类别上将它们实现为类方法。

答案 2 :(得分:0)

我个人认为这应该重复。您最终可能需要自定义其中之一,然后您对防止重复所做的所有工作都会感到恼火。像capitalizedString内发生的事情一样,任何大的事情都可以归类到您正在使用的对象上。