2010-11-16 7 views
85

J'ai 2 classes dont la méthode A et l'autre la méthodeB. Donc dans une nouvelle classe j'ai besoin de surcharger les méthodes methodA et methodB. Alors, comment puis-je réaliser l'héritage multiple dans l'objectif C? Je suis un peu confus avec la syntaxe.Héritage multiple Objective-C

Répondre

127

Objective-C ne prend pas en charge l'héritage multiple et vous n'en avez pas besoin. Composition de l'utilisation:

@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 

Il vous suffit maintenant d'appeler la méthode sur l'ivar correspondant. C'est plus de code, mais il n'y a tout simplement pas d'héritage multiple en tant qu'élément de langage dans l'objectif-C.

+8

Composition est très souvent une meilleure approche à prendre que l'héritage, surtout si vous faire beaucoup de tests unitaires sur le code. Il offre beaucoup plus de flexibilité dans le sens où vous pouvez facilement échanger les implémentations sans redéfinir la classe elle-même. Particulièrement utile lorsque vous voulez, par exemple, échanger ClassA et ClassB contre des objets fantaisie. Même lors de l'exécution, les implémentations d'échange (par exemple FTPFileStore vs LocalFileStore) deviennent plus propres avec la composition. Cela ne veut pas dire que l'héritage n'a pas sa place, mais le besoin d'héritage multiple suggère que je repense à ma conception;) – d11wtq

+1

Je ne comprends pas cela. N'avez-vous pas besoin d'instancier 'ClassA' et' ClassB'? Est-ce que l'appel 'methodA:' sur 'MyClass' appelle automatiquement' methodA: 'sur' ClassA'? – zakdances

+1

Non, mais vous pouvez toujours partager le comportement via le passage de message, à la manière dont la POO était supposée fonctionner à l'origine. Si vous ne croyez pas immédiatement que vous avez besoin d'héritage et que vous envisagez plutôt une solution en utilisant la composition, vous verrez que vous commencez à structurer vos programmes de manière plus facile à gérer. Bien sûr, ObjC a l'héritage de base pour les cas où il est correct de l'utiliser. – d11wtq

-2

connaissez-vous sur les protocoles, les protocoles est la façon de mettre en œuvre l'héritage multiple

+58

-1: Les protocoles sont * très * différents de l'utilisation de l'héritage. – FreeAsInBeer

+12

+1 "Pour capturer les similitudes entre les classes qui ne sont pas hiérarchiquement liées." https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html – pokstad

+7

Dans ce cas, où les deux méthodes seront remplacées, les protocoles feront l'affaire. Dans d'autres cas, lorsque vous souhaitez utiliser l'héritage pour réutiliser du code, les protocoles n'aideraient pas. Cependant, cela peut généralement être résolu en laissant les super classes des classes hériter les unes des autres, ou en les combinant, il y a généralement un moyen de faire les choses correctement si une sous-classe partage effectivement du code avec 2 classes. –

3

Voilà comment je le code singletonPattern comme un « parent » Fondamentalement, j'utilisé une combinaison de protocole et de la catégorie.

La seule chose que je ne peux pas ajouter est un nouveau "ivar" cependant, je peux le pousser avec l'objet associé.

#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 
{ 

} 

Chaque fois que je veux une classe « héritera » ce BGSuperSingleton je fais juste:

#import "NSObject+singleton.h" 

et ajouter @interface MyNewClass() <BGSuperSingleton>

+2

Les catégories ne sont pas héritées multiples. Ils sont un moyen de virer sur des méthodes/fonctions à une classe déjà existante. L'héritage multiple permet à une troisième classe d'être une combinaison d'une ou plusieurs classes (y compris des variables). J'aime les catégories. Les catégories sont très utiles. Mais ils ne sont pas l'héritage multiple. –

+0

Mais une sous-classe de UIViewController peut également "supporter", dans ce cas, un motif singleton si je le souhaite. –

+0

Techniquement tout NSManagedObject "peut maintenant appeler" [obj singleton]. Je mets ceux que je souhaite avec le support du protocole. Aussi bon que l'héritage multiple de toute façon. C'est seulement si je veux que la classe enfant supporte à la fois l'interface et l'implémentation du parent. Si seulement la mise en œuvre alors évidemment la composition est la voie à suivre. –