502 votes

Création d’une classe abstraite en Objective C

Je suis originaire d’un programmeur Java, qui travaille maintenant avec Objective-C. Je voudrais créer une classe abstraite, mais qui ne semble pas être possible en Objective-C. Est-ce possible ?

Si non, comment près d’une classe abstraite peut obtenir en Objective-C ?

628voto

Barry Wark Points 73462

Généralement, Objective-C classe abstraite par convention que si l'auteur des documents d'une classe de base abstraite, il suffit de ne pas l'utiliser sans sous-classement. Il n'existe pas au moment de la compilation de l'application qui empêche l'instanciation d'une classe abstraite, cependant. En fait, il n'y a rien pour empêcher un utilisateur de fournir des implémentations de méthodes abstraites par l'intermédiaire d'une catégorie (c'est à dire au moment de l'exécution). Vous pouvez forcer un utilisateur à au moins remplacer certaines méthodes par le déclenchement d'une exception dans ces méthodes de mise en œuvre dans votre classe abstraite:

[NSException raise:NSInternalInconsistencyException 
            format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)];

Si votre méthode retourne une valeur, c'est un peu plus facile à utiliser

@throw [NSException exceptionWithName:NSInternalInconsistencyException
                               reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
                             userInfo:nil];

comme vous n'avez pas besoin d'ajouter une instruction de retour de la méthode.

Si la classe abstraite est vraiment une interface (c'est à dire n'a pas de méthode concrète mises en œuvre), à l'aide d'un Objectif-C protocole est le plus approprié option.

267voto

Grouchal Points 7053

Non il n’y aucun moyen de créer une classe abstraite en Objective C.

Vous pouvez railler une classe abstraite - en faisant les méthodes / sélecteurs call doesNotRecognizeSelector : et donc une exception, ce qui rend la classe inutilisable.

par exemple :

vous pouvez également le faire pour init.

60voto

Yar Points 25421

Juste riffs sur @Barry Wark la réponse ci-dessus (et la mise à jour pour iOS 4.3) et en laissant cela de ma propre référence:

#define mustOverride() @throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"%s must be overridden in a subclass/category", __PRETTY_FUNCTION__] userInfo:nil]
#define methodNotImplemented() mustOverride()

alors à vos méthodes vous pouvez utiliser cette

- (void) someMethod {
     mustOverride(); // or methodNotImplemented(), same thing
}



Notes: vous ne savez Pas si faire une macro ressembler à une fonction C est une bonne idée ou pas, mais je vais le garder jusqu'à ce scolarisés à l'effet contraire. Je pense qu'il est plus correct d'utiliser NSInvalidArgumentException (plutôt que d' NSInternalInconsistencyException) puisque c'est ce que le système d'exécution de jette, en réponse à l' doesNotRecognizeSelector d'être appelé (voir NSObject docs).

42voto

redfood Points 402

Je sais que cela a été demandé/répondu il y a longtemps, mais la solution je suis juste venu avec est:

  1. Créer un Protocole pour tout ce que vous voulez dans votre "résumé" de la classe
  2. Créer une classe de base (ou peut-être l'appeler abstrait) qui implémente le protocole. Pour toutes les méthodes que vous voulez "abstrait" de les mettre en œuvre dans le .m fichier, mais pas le .h fichier.
  3. Demandez à votre enfant de classe hérite de la classe de base ET de mettre en œuvre le protocole. De cette façon, le compilateur vous donnera un avertissement pour toute méthode dans le protocole qui n'est pas mis en œuvre par votre enfant de la classe.

Ce n'est pas aussi succincte qu'en Java, mais vous n'obtenez souhaité avertissement du compilateur.

35voto

Steve918 Points 863

à partir de l'Omni Group mailing list

Objective-C n'est pas le résumé du compilateur de construction comme Java à cette fois.

Donc tout ce que vous faire est de définir la classe abstraite comme toute autre classe normale et de mettre en œuvre des méthodes de talons pour les méthodes abstraites qui sont soit vide ou un rapport de non-soutien de sélecteur. Par exemple...

- (id)someMethod:(SomeObject*)blah
{
     [self doesNotRecognizeSelector:_cmd];
     return nil;
}

J'ai également effectuer les opérations suivantes pour empêcher l'initialisation de l'abstrait classe via l'initialisation par défaut.

- (id)init
{
     [self doesNotRecognizeSelector:_cmd];
     [self release];
     return nil;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X