Héritage multiple Objective-C


88

J'ai 2 classes, l'une comprend la méthode A et l'autre la méthode B. Donc, dans une nouvelle classe, je dois remplacer les méthodes methodA et methodB. Alors, comment obtenir un héritage multiple dans l'objectif C? Je suis un peu confus avec la syntaxe.

Réponses:


136

Objective-C ne prend pas en charge l'héritage multiple et vous n'en avez pas besoin. Utiliser la composition:

@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 concerné. C'est plus de code, mais il n'y a tout simplement pas d'héritage multiple comme fonctionnalité de langage dans objective-C.


8
La composition est très souvent une meilleure approche à adopter que l'héritage, surtout si vous effectuez beaucoup de tests unitaires sur le code. Il offre beaucoup plus de flexibilité en ce sens que vous pouvez facilement échanger les implémentations sans redéfinir la classe elle-même. Particulièrement pratique lorsque vous souhaitez, par exemple, échanger ClassA et ClassB contre des objets simulés. Même à l'exécution, l'échange d'implémentations (par exemple FTPFileStore vs LocalFileStore) devient plus propre avec la composition. Cela ne signifie pas que l'héritage n'a pas sa place, mais le besoin d'héritage multiple suggérerait que je repense ma conception;)
d11wtq

1
Je ne comprends pas ça. N'avez-vous pas besoin d'instancier ClassAet ClassB? Est -ce que l' appel methodA:à une MyClasscertaine façon appeler automatiquement methodA:sur ClassA?
zakdances

1
Non, mais vous pouvez toujours partager le comportement via la transmission de messages, comme OOP était censé fonctionner à l'origine. Si vous ne pensez pas immédiatement que vous avez besoin d'héritage et que vous envisagez plutôt une solution utilisant la composition, vous constaterez que vous commencez à structurer vos programmes de manière plus maintenable. Bien sûr, ObjC a un héritage de base pour les cas où il est correct de l'utiliser.
d11wtq


1
d11wtq, excellente réponse! De plus, le transfert de message vous permet de sauter l'étape de réimplémentation de la méthodeA et de la méthodeB. Les messages peuvent être automatiquement transmis aux objets appropriés avec juste un peu de travail. developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…
arsenius

3

C'est ainsi que je code singletonPattern en tant que "parent". Fondamentalement, j'ai utilisé une combinaison de protocole et de catégorie.

La seule chose que je ne peux pas ajouter est un nouveau "ivar" cependant, je peux le pousser avec un 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 qu'une classe "hérite" de ce BGSuperSingleton, je fais simplement:

#import "NSObject+singleton.h"

et ajouter @interface MyNewClass () <BGSuperSingleton>


2
Les catégories ne sont pas un héritage multiple. Ils sont une façon de clouer 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 ce ne sont PAS des héritages multiples.
Lloyd Sargent

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

Techniquement, tous les NSManagedObject "peuvent désormais appeler" [obj singleton]. J'ai défini ceux que je souhaite avec le soutien du protocole. Aussi bon que l'héritage multiple de toute façon. C'est seulement si je veux que la classe enfant prenne en charge à la fois l'interface et l'implémentation du parent. Si seulement la mise en œuvre, alors évidemment la composition est la voie à suivre.
Septiadi Agus

Le simple fait d'ajouter le protocole comme <BGSuperSingleton> ne permet pas aux classes d'appeler la méthode "singleton". Vous devez encore l'implémenter ...
CommaToast

-4

Connaissez-vous les protocoles, les protocoles sont le moyen d'implémenter l'héritage multiple


12
+1 "Pour capturer les similitudes entre les classes qui ne sont pas liées hiérarchiquement." developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…
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 ne vous aideront pas. Cependant, cela peut généralement être résolu en laissant les classes superclasses hériter les unes des autres, ou en les combinant, il existe généralement un moyen de faire les choses correctement si une sous-classe partage réellement du code avec 2 classes.
jake_hetfield

vous pouvez combiner le protocole avec une catégorie ou une composition.
Septiadi Agus

-1 car les protocoles ne sont pas du tout là pour l'héritage multiple. De même JAVA, Interfacesne doivent pas fournir ou imiter l'héritage multiple.
thesummersign

1
@FreeAsInBeer De la propre documentation d' Apple Un protocole déclare une interface de programmation que n'importe quelle classe peut choisir d'implémenter. Les protocoles permettent à deux classes éloignées par héritage de communiquer entre elles pour atteindre un certain objectif. Ils offrent ainsi une alternative au sous-classement . Comme vous pouvez le voir, Apple utilise explicitement le sous-classement, c'est-à-dire l'héritage. Peut-être que Nikesh inclure cela dans sa propre réponse serait utile pour clarifier son argument
Chérie
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.