2010-05-18 2 views
14

J'ai créé un protocole que mes classes doivent mettre en œuvre, puis pris en compte certaines fonctionnalités communes dans une classe de base, donc je l'ai fait:Comment éviter d'avertissement « de mise en œuvre incomplète » dans la classe de base partielle

@protocol MyProtocol 
- (void) foo; 
- (void) bar; 
@end 

@interface Base <MyProtocol> 
@end 

@interface Derived_1 : Base 
@end 

@interface Derived_2 : Base 
@end 

@implementation Base 
- (void) foo{ 
//something foo 
} 
@end 

@implementation Derived_1 
- (void) bar{ 
//something bar 1 
} 
@end 

@implementation Derived_2 
- (void) bar{ 
//something bar 2 
} 
@end 

de cette façon, dans mon code, j'utiliser un identifiant générique <MyProtocol>.

Les œuvres de code (tant que base ne sert pas directement) mais le compilateur selfs à la fin de la mise en œuvre de la base avec un avertissement:

Incomplete implementation of class Base

Y at-il un moyen d'éviter cet avertissement ou, encore mieux, une manière plus correcte d'obtenir ce comportement de classe de base abstrait partiellement implémenté dans Objc?

Répondre

12

Vous pourriez peut faire quelque chose comme ceci:

@implementation Base 

- (void)bar 
{ 
    if ([self class] == [Base class]) { 
     [self doesNotRecognizeSelector:_cmd]; 
    } 
} 

@end 

De cette façon, vous avez un implémentation, mais par défaut, il déclenche une exception. Toutefois, si une classe dérivée appelle accidentellement [super bar] ou ne remplace pas bar, l'exception ne être soulevée. Si ce n'est pas ce que vous voulez, vous pouvez simplement le raccourcir à:

@implementation Base 

- (void)bar 
{ 
    [self doesNotRecognizeSelector:_cmd]; 
} 

@end 

Dans ce cas, une exception sera levée, même si une sous-classe appelle [super bar] ou ne remplace pas bar.

+0

ok, cela va au moins imposer l'implémentation dans les classes les plus dérivées. Il serait agréable d'avoir une compilation d'avertissement pour methos inappliquées, cependant, mais je suppose qu'il n'y a aucun moyen (?) Y at-il une bonne façon de faire cette classe de base partielle dans la mise en œuvre Obj-c? – garph0

+0

Pas vraiment. Comme d'autres l'ont noté, Objective-C n'a pas de classes de base abstraites. Toutes les approches que j'ai jamais utilisées pour les imiter ne vous mèneront qu'à mi-chemin. – mipadi

9

Dans votre définition de protocole, vous devez déclarer vos méthodes sous le mot-clé @optional.

Votre code devrait ressembler à ceci:

@protocol MyProtocol 

@optional 
- (void) foo; 
- (void) bar; 

@end 

Voir ce question sur le SO.

+0

Will not @optional faire la mise en œuvre de la méthode facultative également dans les classes dérivées? Je veux la classe la plus dérivée à forcer à mettre en œuvre les méthodes mises en œuvre dans la non classe de base (« bar », dans ce cas). – garph0

+0

@ garph0, Vous ne pouvez pas choisir dans Obj-C. –

1

Dans Obj-C, il n'y a pas de notion de classe abstraite. Donc, vous ne pouvez pas laisser votre classe Base être abstraite (ce qui signifie ne pas implémenter toutes les méthodes dans le protocole). Vous ne pouvez avoir que 2 choix. Laisser la méthode dans le protocole être optionol et ensuite l'implémenter vous-même dans la classe dérivée. Ou, forcer toutes les classes dans la hiérarchie pour la mettre en œuvre, mais laisser l'appelant à faire attention pas appeler ceux de méthode incorrecte

0

que je fais quelque chose comme ça

@protocol MyProtocol 
- (void) foo; 
- (void) bar; 
@end 

@interface BaseAbstract 
- (void) bar; // give a default implementation 
@end 

@interface Derived_1 : BaseAbstract<MyProtocol> 
// you will get a compiler warning for foo() since it is not implemented 

// you will NOT get compiler for bar() warning since a default 
// implementation is inherited 
@end 

@interface Derived_2 : BaseAbstract<MyProtocol> 
@end 

typedef BaseAbstract<MyProtocol> Base; 
Questions connexes