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 -

我需要你的帮助。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
-(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
可以是Robot
rob1
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;
}