Surcharge de méthode en Objective-C?

131

À ma connaissance, Objective-C ne prend pas en charge la surcharge de méthode. Quelle peut être l'alternative à cela en Objective-C? Ou devrais-je toujours utiliser un nom de méthode différent?

suse
la source

Réponses:

193

Correct, objective-C ne prend pas en charge la surcharge de méthode, vous devez donc utiliser des noms de méthode différents.

Notez, cependant, que le "nom de la méthode" inclut les mots-clés de signature de méthode (les noms de paramètres qui précèdent les ":"), donc ce qui suit sont deux méthodes différentes , même si elles commencent toutes les deux "writeToFile":

-(void) writeToFile:(NSString *)path fromInt:(int)anInt;
-(void) writeToFile:(NSString *)path fromString:(NSString *)aString;

(les noms des deux méthodes sont "writeToFile: fromInt:" et "writeToFile: fromString:").

David Gelhar
la source
4
@RaheelSadiq Ce n'est pas une surcharge car les noms des méthodes (dans ObjC: 'selectors') sont différents. Étant différent, ni l'un ni l'autre n'est considéré comme «surchargé». Si writeToFile: from: était défini deux fois, seuls les types de paramètres étant différents, alors ce serait une surcharge. Comme indiqué cependant, cela n'est pas pris en charge dans ObjC comme c'est le cas avec d'autres langages, y compris Java et maintenant Swift.
Chris Hatton
Pas seulement les noms de paramètres eux-mêmes, mais même les deux points font partie du nom de la méthode, de sorte que - (void) writeToFile: (NSString *) path: (int) anInt; et - (void) writeToFile: (NSString ) path: (NSString ) aString; sont également des méthodes différentes.
Kaiserludi
22

Il peut être intéressant de mentionner que même si Objective-C ne prend pas en charge la surcharge de méthode , Clang + LLVM prend en charge la surcharge de fonction pour C. Bien que ce ne soit pas tout à fait ce que vous recherchez, cela pourrait s'avérer utile dans certaines situations (par exemple, implémenter une version légèrement piratée (va à l'encontre de l'encapsulation) du modèle de conception visiteur )

Voici un exemple simple sur le fonctionnement de la surcharge de fonctions:

__attribute__((overloadable)) float area(Circle * this)
{
    return M_PI*this.radius*this.radius;
}

__attribute__((overloadable)) float area(Rectangle * this)
{
    return this.w*this.h;
}

//...
//In your Obj-C methods you can call:
NSLog(@"%f %f", area(rect), area(circle));
Valentin Radu
la source
On pourrait penser que cette allusion, combinée à un swizzling de méthode, pourrait en effet conduire à des méthodes "surchargeables" ... Pourquoi il faudrait, avec idet isKindOfClass:à sa disposition, cependant, est une autre histoire ...
Alex Gray
1
@alexgray Je comprends votre point de vue idet isKindOfClass:couvre la plupart des scénarios pratiques. Une des raisons pour lesquelles vous préférerez peut-être la surcharge est la sélection automatique du type le plus spécifique pris en charge, ce qui entraînerait une légère surcharge à maintenir avec une vérification de type explicite.
Chris Hatton
1
La documentation de Clang dit explicitement que ce qu'elle fait est de fournir le nom de C ++ pour C. les types d'arguments.
Chris Stratton
19

David a raison en ce sens que la surcharge de méthode n'est pas prise en charge dans Objective-C. C'est similaire à PHP dans ce sens. Comme il le souligne également, il est courant de définir deux méthodes ou plus avec des signatures différentes de la manière dont il donne des exemples. Cependant, il est également possible de créer une méthode en utilisant le type "id". Via le type "id", vous pouvez envoyer n'importe quel objet (et toutes les primitives utilisant la classe NSNumber) à la méthode, puis à partir de la méthode elle-même, vous pouvez tester son type et lever l'exception appropriée si nécessaire. Bien que cela ait un impact mineur sur les performances, il sera probablement nominal ou insignifiant, sauf si vous traitez de grandes quantités de données.

- (void) writeToFile: (NSString *)path fromObject: (id)object {
    if (!([object isKindOfClass: [NSNumber class]] || [object isKindOfClass: [NSString class]])) {
         @throw [NSException exceptionWithName: @"InvalidArgumentException" reason: @"Unrecognized parameter type." userInfo: nil];
    }
}

C'est aussi un bel endroit pour implémenter un protocole pour appliquer le type d'objet, ce qui peut être fait comme ceci:

(id<MyProtocol>)object
Ziminji
la source