我最初是一名Java程序员,现在使用Objective-C。我想创建一个抽象类,但这在Objective-C中似乎不可能。这可能吗?
如果不是,在Objective-C中,我能有多接近抽象类?
我最初是一名Java程序员,现在使用Objective-C。我想创建一个抽象类,但这在Objective-C中似乎不可能。这可能吗?
如果不是,在Objective-C中,我能有多接近抽象类?
当前回答
也许这种情况只会发生在开发阶段,所以这是可行的:
- (id)myMethodWithVar:(id)var {
NSAssert(NO, @"You most override myMethodWithVar:");
return nil;
}
其他回答
不,在Objective-C中无法创建抽象类。
你可以模拟一个抽象类——通过让methods/ selectors调用doesNotRecognizeSelector:从而引发一个异常,使该类不可用。
例如:
- (id)someMethod:(SomeObject*)blah
{
[self doesNotRecognizeSelector:_cmd];
return nil;
}
你也可以为init这样做。
我想出的解决办法是:
为“抽象”类中需要的所有内容创建一个协议 创建一个实现协议的基类(也可以称之为抽象类)。对于所有你想要“抽象”的方法,在.m文件中实现它们,而不是在.h文件中实现。 让你的子类继承基类并实现协议。
这样,编译器就会对协议中没有由你的子类实现的任何方法发出警告。
它不像Java中那样简洁,但您确实会得到所需的编译器警告。
在Xcode中(使用clang等),我喜欢使用__attribute__((不可用(…)))来标记抽象类,所以如果你尝试使用它,你会得到一个错误/警告。
它提供了一些防止意外使用该方法的保护。
例子
在基类@interface标记中,"abstract"方法:
- (void)myAbstractMethod:(id)param1 __attribute__((unavailable("You should always override this")));
更进一步,我创建了一个宏:
#define UnavailableMacro(msg) __attribute__((unavailable(msg)))
这让你可以这样做:
- (void)myAbstractMethod:(id)param1 UnavailableMacro(@"You should always override this");
就像我说的,这不是真正的编译器保护,但它和你在不支持抽象方法的语言中得到的一样好。
Cocoa不提供任何所谓抽象的东西。我们可以创建一个只在运行时检查的类抽象,而在编译时不检查。
事实上,Objective-C没有抽象类,但是您可以使用协议来达到同样的效果。下面是例子:
CustomProtocol.h
#import <Foundation/Foundation.h>
@protocol CustomProtocol <NSObject>
@required
- (void)methodA;
@optional
- (void)methodB;
@end
TestProtocol.h
#import <Foundation/Foundation.h>
#import "CustomProtocol.h"
@interface TestProtocol : NSObject <CustomProtocol>
@end
TestProtocol.m
#import "TestProtocol.h"
@implementation TestProtocol
- (void)methodA
{
NSLog(@"methodA...");
}
- (void)methodB
{
NSLog(@"methodB...");
}
@end