8
votes

Objective-C Comment forcer la sous-classe à mettre en œuvre des méthodes?

Une autre façon de formuler cette question: est-il possible pour une sous-classe d'être un délégué de sa super classe? J'essaie de rendre mon code réutilisable dans mon application et d'avoir une situation où la sous-classement doit mettre en œuvre deux méthodes pour qu'elle soit fonctionnelle. Comment puis-je m'assurer que cela se produit? Ou quelle est la bonne façon de définir ces méthodes?

mise à jour

Je ne voulais pas dire que je veux que le compilateur génère des drapeaux. Je veux juste un moyen propre d'organiser mon code. Actuellement, je remplace les méthodes de la superclasse. En utilisant cette approche, la superclasse peut appeler [Super Methodtooverride] et cela fonctionne. Cependant, cela ne me sens pas très propre pour moi car il n'ya aucun moyen de préciser «ce sont les méthodes que vous devriez remplacer» en dehors de mettre un commentaire quelque part.


2 commentaires

Pourquoi avez-vous besoin de respecter cela dans le code? Êtes-vous en train de dire qu'il y aura plusieurs sous-classes possibles, écrites par différentes personnes? La superclasse met-elle en œuvre ces méthodes?


Vous pouvez implémenter le corps de cette méthode avec un contenu par défaut d'un contenu d'exception) avec un message comme cette méthode doit être remplacé par la méthode ), qui force la méthode sera remplacée dans la sous-classe; Pas trop élégant mais le travail est-il assez précisément.


6 Réponses :


2
votes

Si votre question est "Comment puis-je obtenir le compilateur de signaler qu'une certaine classe ne met pas en œuvre une certaine fonction" alors je dirais

  1. Définissez un protocole avec des méthodes non optionnelles - "Par défaut, toutes les méthodes déclarées dans un protocole sont des méthodes requises. Cela signifie que toute classe conforme au protocole doit mettre en œuvre ces méthodes."
  2. Définir une classe ("talon") qui le déclare implémente le protocole
  3. Maintenant, lorsqu'une sous-classe de votre classe de STOP est écrite, le compilateur le signalera comme une erreur si la ou les méthodes obligatoires ne sont pas implémentées

4 commentaires

Je suis allé à une manière légèrement différente. J'ai défini un protocole avec la méthode obligatoire que je voulais pouvoir forcer la sous-classe à mettre en œuvre. J'ai ajouté un talon à la classe de base afin que je puisse appeler la méthode là-bas. Ensuite, j'ai déclaré le soutien du protocole dans la sous-classe. Lorsque la sous-classe n'a pas implémenté la méthode, le compilateur a émis un avertissement (non une erreur) sur la ligne de sous-classe '@Implementatation indiquant qu'il n'avait pas mis en œuvre la méthode définie dans le protocole.


Pourquoi a-t-il émis un avertissement si la classe de base avait la méthode?


@Carlsmith mais ne devriez-vous pas oublier de déclarer que la sous-classe adopte le protocole?


Non, il vous suffit de vous rappeler de dériver de la classe de stub à un moment donné de la hiérarchie de la classe.



8
votes

dans Obj-C, il n'est pas possible de forcer les sous-classes à écraser méthodes de sa superclasse. Mais vous pouvez soulever une exception dans la superclasse, si cela ne sera jamais appelé parce que la sous-classe n'a pas mis en œuvre une certaine méthode. Mais une sous-classe peut être une déléguée de sa superclasse, si la superclasse ne met pas en œuvre certaines méthodes et que vous pouvez appliquer que le délégué implémente ces méthodes, si la superclasse spécifie le protocole, c'est-à-dire méthodes requises, et La sous-classe l'adopte.


6 commentaires

Vous feriez donc self.delegate = auto ?


Je ferais une instanceOfsuperclass.delegate = instanceofsubclass si elle implémente les méthodes requises.


Le auto Je faisais référence à la sous-classe de la superclasse.


@Nick: Désolé, j'étais hier soir à fatigue de voir votre point de vue. Oui, si "délégué" est une propriété de la superclasse, la déclaration auto-self.delegate = Soi, exécutée dans la sous-classe, attribue le "soi" de la sous-classe au délégué de la superclasse. Et si la superclasse nécessite par protocole par protocole que la sous-classe, qui adopte le protocole, implémente une méthode "test", puis la déclaration [Self.Delegate Test] dans la sous-classe exécute "Test" dans la sous-classe. J'espère que je t'ai bien compris cette fois-ci.


@ Reinhardmänner Je pense que cela créera un cycle de référence juste?


@Confile généralement, il faut utiliser des références faibles pour les délégués pour éviter les cycles de référence, voir << a href = "http://stackoverflow.com/questions/8449040/why-utilisateur-weak-pointer-for-délégation" title = "pourquoi Utilisez un pointeur faible pour la délégation "> Stackoverflow.com/Questtions/8449040/... >



3
votes

Il n'y a aucun moyen de le faire en compilation. Cependant, vous pouvez soulever une exception dans la classe de base.

quelque chose comme ceci: xxx


0 commentaires

1
votes

Je sais que c'est affreux, mais supposé que vous devez le faire depuis que votre SDK 3RDParty nécessite ce modèle de conception, vous pouvez utiliser un motif d'usine:

supposé alors avoir la classe de base myparentepiclient forte > et deux sous-classes comme myFacebookApiclient strong> et myGoogleplusapiclient strong> et que vous faites quelque chose comme p> xxx pré>

et que vous avez défini xxx pré>

et vous avez remplacé cela dans les deux sous-classes p> xxx pré>

et p> xxx pré >

Ensuite, vous faites dans votre contrôleur P>

if([self isKindOfClass:[MyFacebookAPIClient class]]) {
        [((MyFacebookAPIClient*)self) callAPI];
    } else if([self isKindOfClass:[MyGooglePlusAPIClient class]]) {
       [((MyGooglePlusAPIClient*)self) callAPI];
    }
  }


0 commentaires

7
votes

Si vous souhaitez forcer votre sous-classe à mettre en œuvre des méthodes de Super Class, vous pouvez le faire comme ci-dessous:

[super someMethod:bla];


2 commentaires

Dans la construction ou en runtime?


Le problème est que, en tant que programmeur, vous souhaitez détecter le problème le plus tôt possible. C'est-à-dire au moment de la compilation ou à Linter temps. Si vous n'êtes pas implémenter quelque chose par erreur, vous le détecterez à l'exécution (étape ultérieure du processus de développement) qui est généralement plus coûteux à résoudre en termes de temps et d'argent.



1
votes

Le uigesturerecognizersubclass.h code> de Uikit mérite un coup d'œil, qui a toutes les méthodes protégées qui devraient être remplacées et que l'en-tête n'est pas dans le cadre, il est seulement inclus dans les sous-classes ". m fichiers. En outre, de nos jours, vous pouvez étiqueter des méthodes avec ns_requires_super code> pour exiger des substitutions à appeler super, mais il ne peut être utilisé que dans les interfaces, pas uniquement des protocoles afin d'influencer votre conception.

pour le code super avancé, NsaccessibilityProtocols.h Code> Dans AppKit utilise une balise de protocole pour exiger des sous-classes pour réapparquer des méthodes, même si elles sont déjà implémentées par une superclasse. Voici un exemple de celui que vous pouvez coller directement dans l'en-tête de votre projet Xcode actuellement ouvert: P>

NS_PROTOCOL_REQUIRES_EXPLICIT_IMPLEMENTATION
@protocol Protocol
@property (readonly) id theWorstOfTimes;
// -(void)testMethod; // uncomment to test problem
@end

// In this example, ClassA adopts the protocol.
@interface ClassA : NSObject <Protocol>
@property (readonly) id theWorstOfTimes;
@end

@implementation ClassA
- (id)theWorstOfTimes{
    return nil; // default implementation does nothing
}
-(void)testMethod{}
@end

// This class subclasses ClassA (which also adopts 'Protocol').
@interface ClassB : ClassA <Protocol>
@end

@implementation ClassB // expected-warning {{property 'theWorstOfTimes' requires method 'theWorstOfTimes' to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation}} 
@end


5 commentaires

En fait, la question portait sur des méthodes, pas sur les propriétés et pour les propriétés qu'il contient pas travail, comme vous l'avez dit (peut-être en raison d'un bug). Mais votre réponse est de toute façon intéressante, merci!


Je suppose que vous avez mal compris, cela fonctionne pour les propriétés. Cela fonctionnera également pour des méthodes à nouveau une fois qu'ils annulent que la correction de bugs que j'ai mentionnée.


Je pense que je vous ai bien compris: Cela ne fonctionne pas pour des méthodes depuis 2014 , mais peut-être Cela fonctionnera à nouveau à l'avenir. Et la question était sur méthodes .


J'espère que nous pourrons le faire résoudre. J'ai ajouté d'autres pensées que j'ai dû au début de la réponse, peut-être que vous pouvez utiliser NS_Requires_super.


De plus, lorsque Xcode propose de "corriger" le problème, il ajoute correctement les talons de méthode.