的确的目标-C的支持混合像的红宝石?
-
21-09-2019 - |
题
在红宝石,有的模块,并可以延长一级通过"混合"的模块。
module MyModule
def printone
print "one"
end
end
class MyClass
include MyModule
end
theOne = MyClass.new
theOne.printone
>> one
在目标C中,我发现,我有一套共同方法,我想若干类"继承".什么其它的方式我可以实现这一目标没有建立一个共同的类和产生所有从这一共同类?
解决方案
编辑:改变增加,因为有些人觉得我有责任的限制的目标。
简短的回答:你不能。目标-C没有等效的红宝石混入.
稍微少简短的回答:目标-C确实有东西可以说是相同的口味:协议。协议(接口,在一些其他语言),是一种方式定义设定的方法一类,采用这一协议是承诺实施。议定书没有提供执行情况。这种限制可防止使用协议作为一个确切的相当于红宝石混入.
甚至少简短的回答: 然而,目标-C运行时具有暴露的API可以让你玩的动态特征的语言。然后你一步之外的语言,但是你可以有协议,与默认的实现(也称为具体的协议)。弗拉基米尔的答复显示一种方式做到这一点。在这一点上,它似乎对我来说你得到红宝石的混入正常的。
但是,我不确定我会推荐这样做。在大多数情况下,其他模式适合该法案没有玩游戏的运行时间。例如,你可以有一个子对象,执行混合方法(有一个 而不是的 是-).玩的运行时确定,但有2个缺点:
你让你的代码不可读的,因为它需要的读者知道更多的语言。你确定你可以(并应该)的评论,但请记住,任何必要的评论可以看作是一个执行情况的缺陷。
取决于你 那 执行《语言。肯定的是,苹果的平台,到目前为止的最为常见的目标-C但不要忘记Cocotron或GnuStep(或Etoilé)它们具有不同的运行时,它可以或不可以兼容的苹果上的尊重。
作为一个侧面说明,我状态下这一类别无法加入国家(例的变量)的一类。通过使用运行时API,你可以解除这一限制。这是超出范围的这个答案但是。
只要回答:
两个目标-C功能看起来像可能的候选人:类别和议定书。类别并不真正正确的选择在这里,如果我理解这个问题的正确。正确的特征是协议。
让我举一个例子。假设你想要一堆的类为具有特定的能力称为"唱"。然后你定义的协议:
@protocol Singer
- (void) sing;
@end
现在你可以宣布,任何你自己的课程,采用协议下的方式:
@interface Rectangle : Shape <Singer> {
<snip>
@end
@interface Car : Vehicle <Singer> {
<snip>
@end
通过声明,他们通过该协议,他们承诺执行《 sing
法。例如:
@implementation Rectangle
- (void) sing {
[self flashInBrightColors];
}
@end
@implementation Car
- (void) sing {
[self honk];
}
@end
然后你使用这些类例如像这样:
void choral(NSArray *choir) // the choir holds any kind of singer
{
id<Singer> aSinger;
for (aSinger in choir) {
[aSinger sing];
}
}
注意歌手的阵不需要有一个共同的超类。还请注意这一类只能有一个超类,但许多通过的协议。注意到最后这一类型的检查是通过编译器。
在生效,该议定书》机制是多个继承使用该混合模式。多个继承受到严重限制,因为协议不能添加新的实例变量一类。一议定书》仅仅描述了一个公共口者必须实现。不像的红宝石的模块,它不包含一个实现。
这是大多数。让我们提一类别。
一个类别是宣布不在角括号内,但是之间的括号。不同的是,一个类别可以被定义为一个现有类扩大它没有继承。你甚至可以做这样一种系统类。你可以想象,这有可能使用分类来实现类似的东西混合.他们是用这种方式很长一段时间通常为类别 NSObject
(典型的根的继承的层次),以这样的程度,他们被称为"非正式"协议。
它是非正式的,因为1-没有类型检查是通过编译器,2-执行《议定书》的方法是可选择的。
没有今天需要使用类别的协议,特别是因为正式的协议现在可以宣告,他们的一些方法是可选择的关键字 @optional
或者需要的(默认)与 @required
.
类别,仍是有用的增加一些领域特定行为为现有类。 NSString
是一个共同的目标。
它还指出,大多数(如果不是所有的) NSObject
设施事实上是宣布中的一个 NSObject
协议。这意味着它不是真正的引人注目的使用 NSObject
作为一个共同的超类的所有类,虽然这仍然是常见的做由于历史的原因,嗯...因为没有缺点这样做。但是,一些系统的类别,例如 NSProxy
, , 不 NSObject
.
其他提示
无耻插头: ObjectiveMixin
它利用在运行时添加方法的一类(而不是类别,这是唯一的编译时)的Objective-C运行的能力。检查出来,它的工作原理相当不错,并以类似的方式,以Ruby的混入。
可以使用的#include字面上混入的代码。这是不可取的,是针对在Objective-C所有的宗教,但完美的作品。
请,不这样做的生产代码。
作为示例的文件中:强>
MixinModule.header (不应该被编译或复制到目标)
-(void)hello;
MixinModule.body (不应该被编译或复制到目标)
-(void)hello{
NSLog(@"Hello");
}
<强>在混合类:强>
@interface MixinTest : NSObject
#include "MixinModule.header"
@end
@implementation MixinTest
#include "MixinModule.body"
@end
<强>使用情况:强>
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]){
@autoreleasepool {
[[[MixinTest new] autorelease] hello];
}
return 0;
}
请,不这样做的生产代码。强>
这是我对在Objective-C执行的混入,而不直接使用Objective-C运行。也许是有帮助的人: https://stackoverflow.com/a/19661059/171933