在Objective-C中模拟多重继承

在Objective-C中模拟多重继承,objective-c,inheritance,architecture,multiple-inheritance,Objective C,Inheritance,Architecture,Multiple Inheritance,我的UIViewControllers(我们称之为MyViewController)有一个抽象类,它覆盖了一些基本方法,如viewDidLoad或viewdiddemouse。在这种方法中,需要做一些准备,比如为导航栏设置颜色,或者准备栏按钮等等 现在,我也希望我的UITableViewControllers具有这种基本行为。因此,我创建了一个新类,它继承了UITableViewController(我们称之为MyTableViewController),并从MyViewController复制

我的
UIViewControllers
(我们称之为
MyViewController
)有一个抽象类,它覆盖了一些基本方法,如
viewDidLoad
viewdiddemouse
。在这种方法中,需要做一些准备,比如为导航栏设置颜色,或者准备栏按钮等等

现在,我也希望我的
UITableViewControllers
具有这种基本行为。因此,我创建了一个新类,它继承了
UITableViewController
(我们称之为
MyTableViewController
),并从
MyViewController
复制了99%的代码

在这张图中,您可以看到我当前的体系结构。列出了重写的方法,其中调用了其他私有方法。同样,
MyViewController
MyTableViewController
共享99%的代码库(唯一的区别是类和超类的名称)

显然,这是废话


有没有一个优雅的解决方案可以使
MyTableViewController
成为
MyViewController
UITableViewController
的子类?

这是一个建议,但我不知道它有多有用,因为我不知道您的代码

可以在UIViewcontroller类的类别中实现一组方法。例如:

@implementation UIViewController (myCategory)
- (void)setupColors;
...
@end
由于MyViewcontroller和MyTableViewcontroller都继承自UIViewController,因此它们将继承您的方法

在这两种实现中,您唯一要复制的是这些函数的调用,但重复的代码要少得多

- viewDidLoad...
{
     [self setupColors];
}

如果重写方法,请务必小心,因为不能像在继承类中那样对类别调用[super…],公共方法的共享实现可以通过类别或组合来完成。由于类别不能用于直接重写现有接口(例如viewDidLoad:),因此需要将私有方法放入类别中,并从子类重写中调用它们。另一种选择是将共享实现放在单独的类(可能是单例)中,并将该类的实例组合为MyViewController和MyTableViewController的属性,例如:

@interface MyViewController : UIViewController
@property (nonatomic, strong) MyControllerStyler *controllerStyler;
@end

@implementation MyViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [controllerStyler viewDidLoad];
}
...etc...
如果需要,组合类的方法可以引用控制器,例如:

@interface MyControllerStyler : NSObject

- (void)viewDidLoadInController: (UIViewController *)controller;
...etc...

虽然在本例中,一个类别似乎很好,但如果您的扩展集中表示设计的一个有意义的单元(例如视觉样式属性的集合),则可能需要一个或多个单独的对象来更好地表示您的意图。

对于少数类来说,这可能是可行的。但我必须复制/粘贴每个子类50行。只要我有5个以上的子类,就会有更多的代码要用这个解决方案来复制。50行并不是那么多。无论如何,你会意识到,如果有其他选择(在我的脑海中有几个),你仍然需要复制一些代码。50行*n subclass=数量巨大。但到目前为止,你的努力是值得的。@MarcMosby如果你使用像这里建议的策略模式,您应该只需要将这些行添加到一些关键方法中,然后始终对这些方法进行子类化。除了
UITableViewController
UIViewController
UICollectionViewController
之外,我想不出还有多少其他视图控制器可以作为子类。你可以用你的个人基类版本来调用你的策略方法,比如ViewDidAspect或rotation之类的东西。我一开始没有得到它,但是你的解决方案现在非常有意义。谢谢@jasoncoo和Merlevede。