Objective-C多重继承


88

我有2个类,一个包含methodA,另一个包含methodB。因此,在新类中,我需要重写方法methodA和methodB。那么如何在目标C中实现多重继承呢?我对语法有点困惑。

Answers:


136

Objective-C不支持多重继承,您也不需要它。使用组成:

@interface ClassA : NSObject {
}

-(void)methodA;

@end

@interface ClassB : NSObject {
}

-(void)methodB;

@end

@interface MyClass : NSObject {
  ClassA *a;
  ClassB *b;
}

-(id)initWithA:(ClassA *)anA b:(ClassB *)aB;

-(void)methodA;
-(void)methodB;

@end

现在,您只需要在相关的ivar上调用该方法。它是更多的代码,但是在Objective-C中,语言特性没有多重继承。


8
与继承相比,组合通常是更好的方法,尤其是在对代码进行大量单元测试的情况下。它提供了更大的灵活性,因为您可以轻松地交换实现,而无需重新定义类本身。例如,当您想将ClassA和ClassB交换为模拟对象时,此功能特别方便。即使在运行时,换出的实现(例如FTPFileStore与LocalFileStore)也变得更加干净。那并不意味着继承就没有它的位置,但是对多重继承的需求表明我重新考虑了我的设计;)
d11wtq 2010年

1
我不明白 你不需要实例化ClassAClassB?是否呼吁methodA:MyClass某种程度上自动调用methodA:ClassA
zakdances

1
不,但是您仍然可以通过消息传递来共享行为,这是OOP最初应该起作用的方式。如果您不立即想到需要继承,而是考虑使用组合的解决方案,则会发现您开始以一种更易于维护的方式来构造程序。当然,对于正确使用ObjC的情况,它具有基本的继承性。
d11wtq 2013年


1
d11wtq,一个不错的答案!另外,消息转发使您可以跳过重新实现methodA和methodB的步骤。只需少量工作,即可将邮件自动转发到适当的对象。 developer.apple.com/library/mac/documentation/Cocoa/Conceptual/...
arsenius

3

这就是我将singletonPattern编码为“父母”的方式,基本上我使用了协议和类别的组合。

我唯一不能添加的是新的“ ivar”,但是,我可以将其与关联对象一起推送。

#import <Foundation/Foundation.h>
@protocol BGSuperSingleton
+(id) singleton1;
+(instancetype)singleton;
@end

@interface NSObject (singleton) <BGSuperSingleton>

@end

static NSMutableDictionary * allTheSingletons;

+(instancetype)singleton
{
    return [self singleton1];
}
+(id) singleton1
{
    NSString* className = NSStringFromClass([self class]);

    if (!allTheSingletons)
    {
        allTheSingletons = NSMutableDictionary.dictionary;
    }

    id result = allTheSingletons[className];

    //PO(result);
    if (result==nil)
    {
        result = [[[self class] alloc]init];
        allTheSingletons[className]=result;
        [result additionalInitialization];
    }
    return result;
}

-(void) additionalInitialization
{

}

每当我想让班级“继承”此BGSuperSingleton时,我就这样做:

#import "NSObject+singleton.h"

并添加 @interface MyNewClass () <BGSuperSingleton>


2
类别不是多重继承。它们是将方法/函数添加到现有类的一种方式。多重继承允许第三类成为一个或多个类(包括变量)的组合。我喜欢类别。类别非常有用。但是它们不是多重继承。
劳埃德·萨金特

但是UIViewController的子类也可以“支持”,在这种情况下,我希望使用单例模式。
Septiadi Agus

从技术上讲,所有NSManagedObject现在都可以“调用” [obj单例]。我在协议支持下设置了我希望的那些。无论如何,都和多重继承一样好。仅当我希望子类同时支持父类的接口和实现时。如果只是实现,那么显然组合是可行的方法。
Septiadi Agus

仅添加诸如<BGSuperSingleton>之类的协议并不能使这些类能够调用“ singleton”方法。您仍然必须实现它……
CommaToast

-4

您了解协议,协议是实现多重继承的方式


12
+1“捕获没有层次关系的类之间的相似性。” developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/...
pokstad

7
在这种情况下,两种方法都将被覆盖,协议将解决问题。在其他情况下,当您想使用继承重用代码时,协议将无济于事。但是,通常可以通过让类的超类彼此继承或将它们组合来解决,如果子类实际上与两个类共享代码,通常可以通过一种方法来解决。
jake_hetfield 2012年

您可以将协议与类别或组成相结合。
Septiadi Agus

-1是因为协议根本不存在多重继承。同样在中JAVAInterfaces也不提供或模仿多重继承。
sumsumsign

1
@FreeAsInBeer来自Apple自己的文档 协议声明任何类都可以选择实现的编程接口。协议使通过继承关系远的两个类彼此通信以实现某个目标成为可能。因此,它们提供了子类化替代方法。如您所见,Apple 明确使用子类化(即继承)。也许耐克什(Nikesh)在他自己的回答中包括这一点将有助于澄清他的论点
亲爱的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.