【问题标题】:Objective-C property/inheritance/design adviceObjective-C 属性/继承/设计建议
【发布时间】:2012-04-19 05:22:15
【问题描述】:

我有一个基类MyDevice。我还有一个基类MyDeviceController:

@interface MyDeviceController : NSObject {
    MyDevice* device;
}

@property (retain) MyDevice* device;

@end

MyDeviceController 在设备的 setter 中有一些通用逻辑,我想保留在子类中。

我有两个 MyDevice 子类:

@interface MyAudioDevice : MyDevice

- (void)audioMethod;

@end

@interface MyVideoDevice : MyDevice

- (void)videoMethod;

@end

还有 MyDeviceController 的两个子类:MyVideoDeviceControllerMyAudioDeviceController,它们必须具有 MyVideoDeviceMyAudioDevice 作为 device 属性。

实现这两个 MyDeviceController 子类的最佳方法是什么?或者这种情况可能有一些模式?

更新

我找到的第一个解决方案是在My[Audio|Video]DeviceController中重新声明属性:

@interface MyAudioDeviceController : MyDeviceController

@property (retain) MyAudioDevice* device;

@end

并在实施中

@implementation MyAudioDeviceController

- (void)setDevice:(MyAudioDevice*)device
{
    NSAssert([device isKindOfClass:[MyAudioDevice class]], @"What's the...?");
    [super setDevice:device];
}

- (MyAudioDevice*)device
{
    return (MyAudioDevice*)[super device];
}

@end

在这个解决方案中我唯一不喜欢的是重新定义 device 方法。

可能有其他解决方案吗?

【问题讨论】:

  • 为 mydevice(s) 使用一个接口(我忘记了在 Objective-c 中调用了什么),然后对其进行编程,以便控制器可以接受任何类型的设备。
  • @TomIngram:协议就是你所追求的

标签: objective-c oop design-patterns inheritance properties


【解决方案1】:

在您的控制器中重写-(void)setDevice:(Device *)device 以确保它只接受MyVideoDeviceMyAudioDevice。如果您需要通用控制器的逻辑,只需将其复制过来即可。

【讨论】:

  • 是的,但我还需要device 方法来返回MyAudioDevice。我还打电话给我的[super setDevice:device] 以避免重复代码。我已经更新了问题。
【解决方案2】:

我的 Objective-c 有点偏离,但希望这能让您了解我在评论中的意思。

“为我的设备使用一个接口(我忘记了在 Objective-c 中调用了什么),然后对其进行编程,以便控制器可以接受任何类型的设备。”

理论上,特定于设备的所有内容都应该是私有的,并且您使用通用接口,因此您可以拥有许多不同的具体设备而不必担心。

一个接口例如

@protocol MediaDevice
- void play
- void stop
- void pause
@end

实现

@interface AudioDevice : NSObject <MediaDevice> 
@end

@implementation AudioDevice
- void play
{
    [super play]
}
// ...
@end

控制器

@interface DeviceController : NSObject
@property (readwrite, assign) MediaDevice device
@end

【讨论】:

  • 但是对于不同的设备我有不同的方法:videoMethod 用于MyVideoDeviceaudioMethod 用于MyAudioDevice,这就是为什么我必须在device 中使用device 作为MyAudioDeviceMyAudioDeviceController,不像MyDevice
【解决方案3】:

我想我找到了最好的解决方案。解决方案是在属性device 的实现中使用@dynamic 指令。

@interface MyAudioDeviceController : MyDeviceController

@property (retain) MyAudioDevice* device;

@end

及实施:

@implementation MyAudioDeviceController

@dynamic device;

- (void)setDevice:(MyAudioDevice*)device
{
    NSAssert([device isKindOfClass:[MyAudioDevice class]], @"What's the...?");
    [super setDevice:device];
}

- (void)someAduioDeviceControllerMethod
{
    [self.device audioMethod];
}

@end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    • 2012-09-23
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    • 2012-03-10
    相关资源
    最近更新 更多