在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。