Objective-C中的抽象类
我需要你的帮助。Objective-C中的以下问题:Objective-C中的抽象类,objective-c,protocols,abstract-class,cocoa-design-patterns,Objective C,Protocols,Abstract Class,Cocoa Design Patterns,我需要你的帮助。Objective-C中的以下问题: // Robot.h @protocol RobotProtocol <NSObject> -(void)doWork; @end @interface Robot : NSObject // Rob1 sublass of class Robot // rob1.h @interface Rob1 : Robot <RobotProtocol> // rob1.m @implementation -
// Robot.h
@protocol RobotProtocol <NSObject>
-(void)doWork;
@end
@interface Robot : NSObject
// Rob1 sublass of class Robot
// rob1.h
@interface Rob1 : Robot <RobotProtocol>
// rob1.m
@implementation
-(void)doWork
{
// print 'robot 1'
}
// Rob2 sublass of class Robot
// rob2.h
@interface Rob2 : Robot <RobotProtocol>
// rob2.m
@implementation
-(void)doWork
{
// print 'robot 2'
}
// Task.h
@interface Task : NSObject
{
Robot *rob;
}
// Task.m
@implementation
- (id)init
{
if ([super init]) {
rob = [[Rob1 alloc] init]; // or Rob2 !!
}
return self;
}
-(void)doSomething
{
[rob doWork]; // how to make sure, that this is implemented, depending on Rob1 or Rob2
}
//Robot.h
@协议机器人协议
-(无效)嫁妆;
@结束
@接口机器人:NSObject
//Rob1类机器人的子类
//rob1.h
@接口Rob1:机器人
//rob1.m
@实施
-(无效)嫁妆
{
//打印“机器人1”
}
//Rob2类机器人的子类
//rob2.h
@接口Rob2:机器人
//rob2.m
@实施
-(无效)嫁妆
{
//打印“机器人2”
}
//任务.h
@接口任务:NSObject
{
机器人*罗布;
}
//任务
@实施
-(id)init
{
if([super init]){
rob=[[Rob1 alloc]init];//或Rob2!!
}
回归自我;
}
-(无效)剂量
{
[rob doWork];//如何确保实现此功能,具体取决于Rob1或Rob2
}
Robot
及其子类应该如何实现,即Robot*rob
可以是Robotrob1
、rob2
、…
的子类之一,以及方法doWork:(BOOL)val代码>可以调用吗?我的第一个想法是将Robot
实现为一个抽象类,但不幸的是,Objective-C中没有抽象类
目前我正在使用协议,但我没有信心。由于不确定是否实现了doWork,编译器抱怨
“Robot”可能对“doWork”没有响应
谢谢你的想法。我猜你是想做这样的事情,但是没有代码很难说
//Robot.h
{
-(void)doWork:(BOOL)myBool
}
//Robot.m
{
-(void)doWork:(BOOL)myBool
{
if (myBool)
{
//do something
}
else
{
//do something else
}
}
}
//Task.h
{
#include"Robot.h"
}
//Task.m
{
Robot *rob = [[Robot rob] alloc] init];
[rob doWork:YES];
}
Objective-C没有java中的抽象类。只需创建一个名为Robot的超类并将其子类化。。您甚至可以通过重写init并立即销毁自身来阻止类的实例化(尽管我不太确定这种方法的“核心性”)
无论如何,这不应该是个问题
还有一个方便的技巧,可以通过使用
if( [rob respondsToSelector:@selector(doWork:)] ) { [rob doWork:value]; }
这通常用于使协议中的方法成为可选的,以便在运行时调用给定对象不存在的方法时不会出错。协议应该有效
@protocol RobotProtocol <NSObject>
@required
- (void)doWork:(BOOL)flag;
@end
@interface Robot1 : NSObject <RobotProtocol>
@end
@implementation Robot1
- (void)doWork:(BOOL)flag
{
}
@end
更新
查看代码后,@interface Robot:NSObject
应该是@interface Robot:NSObject
。问题是你根本不需要@接口Robot:NSObject
。您只需使用id
。这是抽象类的名称。任何试图调用doWork的方法都知道RobotProtocol吗?您可能需要导入包含它的任何头文件
值得一提的是,做你想做的事情的公认方法是只声明超类是什么(Robot),声明并实现带有空实体的方法(如果它们没有被子类覆盖的话,可能会抛出一个NSException),然后创建你的子类(SubRobot,或者你有的)。协议更多,因此不同类型的类可以实现一些已知的方法,而不是用作事实上的抽象超类。正如许多人所说,Objective-C中没有抽象类。我个人喜欢注释+运行时检查。代码如下:
@interface Abstract : NSObject {
}
// Abstract method
- (Foo*)doSomething;
@end
@implementation Abstract
// Abstract method
- (Foo*)doSomething {
[_self doesntRecognizeSelector:_cmd];
return nil;
}
@end
如果您真的想使用“抽象”的东西并进行编译时检查,我认为您必须使用协议。为此,您需要稍微更改代码。特别是,您应该声明您的变量符合协议,id
或Robot*
取决于更适合您的需要:
// Task.h
@interface Task : Robot <RobotProtocol>
{
id<RobotProtocol> rob;
}
//Task.h
@接口任务:机器人
{
我是罗布;
}
您能发布完整的目标C代码吗?定义和使用?您是否尝试过使用错误断言实现方法,以便它们在运行时触发?不如编译时检查好,但这至少可以强制您重写。在init方法中引发异常。感谢您的想法,但应该在编译时检查。谢谢。我试过了,但我的错误是在我的任务类id*robot
(with*)中声明了,这不起作用!
// Task.h
@interface Task : Robot <RobotProtocol>
{
id<RobotProtocol> rob;
}