Metodo di sovraccarico in Objective-C?


131

Per quanto ne so, Objective-C non supporta il sovraccarico del metodo. Quale può essere l'alternativa per questo in Objective-C? O dovrei sempre usare un nome di metodo diverso?

Risposte:


193

Obiettivo-C corretto non supporta il sovraccarico del metodo, quindi è necessario utilizzare nomi di metodi diversi.

Si noti, tuttavia, che il "nome metodo" include le parole chiave della firma del metodo (i nomi dei parametri che precedono il ":" s), quindi i seguenti sono due metodi diversi , anche se entrambi iniziano a "writeToFile":

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

(i nomi dei due metodi sono "writeToFile: fromInt:" e "writeToFile: fromString:").


4
@RaheelSadiq Non è un sovraccarico perché i nomi dei metodi (in ObjC: 'selettori') sono diversi. Essendo diverso, nessuno dei due è considerato "sovraccarico". Se writeToFile: from: sono stati definiti due volte, con solo i tipi di parametro diversi, ciò sovraccaricherebbe. Come affermato, tuttavia, questo non è supportato in ObjC come in altre lingue tra cui Java e ora Swift.
Chris Hatton,

Non solo i nomi dei parametri stessi, ma anche i due punti fanno parte del nome del metodo, quindi - (void) writeToFile: (NSString *) path: (int) anInt; e - (void) writeToFile: (NSString ) path: (NSString ) aString; sono anche metodi diversi.
Kaiserludi,

22

Vale la pena ricordare che anche se Objective-C non supporta il sovraccarico del metodo , Clang + LLVM supporta il sovraccarico delle funzioni per C. Sebbene non sia proprio quello che stai cercando, potrebbe rivelarsi utile in alcune situazioni (ad esempio, quando implementare una versione leggermente compromessa (va contro l'incapsulamento) del modello di progettazione del visitatore )

Ecco un semplice esempio su come funziona il sovraccarico delle funzioni:

__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));

Si potrebbe pensare che questo suggerimento, combinato con il metodo frizzante, potrebbe davvero portare a metodi "sovraccaricabili" ... Perché uno dovrebbe, con ide isKindOfClass:a sua disposizione, però, è una storia diversa ...
Alex Gray,

1
@alexgray Vedo il tuo punto ide isKindOfClass:copro la maggior parte degli scenari pratici. Uno dei motivi per cui potresti preferire il sovraccarico è la selezione automatica del tipo più specifico previsto, che comporterebbe un piccolo sovraccarico da mantenere con un controllo esplicito del tipo.
Chris Hatton,

1
La documentazione di Clang afferma esplicitamente che ciò che fa è fornire il nome C ++ che manipola il C. E questo è fondamentalmente solo il compilatore che fa automaticamente dietro le quinte quello che si fa in Objective-C dando nomi di metodi che si distinguono per racchiudendo (in forma più lunga) i tipi di argomento.
Chris Stratton,

19

David ha ragione nel fatto che il sovraccarico non è supportato in Objective-C. È simile a PHP in questo senso. Come sottolinea anche, è prassi comune definire due o più metodi con firme diverse nel modo in cui egli illustra. Tuttavia, è anche possibile creare un metodo usando il tipo "id". Tramite il tipo "id", è possibile inviare qualsiasi metodo (e qualsiasi primitiva utilizzando la classe NSNumber) al metodo e quindi all'interno del metodo stesso è possibile testarne il tipo e, se necessario, generare l'eccezione appropriata. Sebbene ciò abbia un impatto minore sulle prestazioni, molto probabilmente sarà nominale o insignificante a meno che non si stiano elaborando grandi quantità di dati.

- (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];
    }
}

Questo è anche un bel posto per implementare un protocollo per imporre il tipo di oggetto, che può essere fatto in questo modo:

(id<MyProtocol>)object
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.