Metode kelebihan beban di Objective-C?

131

Sejauh pengetahuan saya, Objective-C tidak mendukung metode overloading. Apa yang bisa menjadi alternatif untuk ini di Objective-C? Atau haruskah saya selalu menggunakan nama metode yang berbeda?

suse
sumber

Jawaban:

193

Benar, objektif-C tidak mendukung kelebihan metode, jadi Anda harus menggunakan nama metode yang berbeda.

Namun, perhatikan bahwa "nama metode" mencakup kata kunci tanda tangan metode (nama parameter yang muncul sebelum ":"), jadi berikut adalah dua metode yang berbeda , meskipun keduanya memulai "writeToFile":

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

(nama kedua metode tersebut adalah "writeToFile: fromInt:" dan "writeToFile: fromString:").

David Gelhar
sumber
4
@ RaheelSadiq Tidak kelebihan karena nama metode (Dalam ObjC: 'penyeleksi') berbeda. Menjadi berbeda, tidak ada yang dianggap 'kelebihan beban'. Jika writeToFile: from: didefinisikan dua kali, dengan hanya tipe parameter yang berbeda, maka itu akan menjadi overloading. Seperti yang dinyatakan, ini tidak didukung dalam ObjC seperti halnya dengan bahasa lain termasuk Java dan sekarang Swift.
Chris Hatton
Bukan hanya nama parameter itu sendiri, tetapi bahkan titik dua adalah bagian dari nama metode, sehingga - (void) writeToFile: (NSString *) path: (int) anInt; dan - (void) writeToFile: (NSString ) path: (NSString ) aString; juga merupakan metode yang berbeda.
Kaiserludi
22

Mungkin perlu disebutkan bahwa bahkan jika Objective-C tidak mendukung metode overloading, Dentang + LLVM mendukung fungsi overloading untuk C. Meskipun tidak sesuai dengan yang Anda cari, itu bisa terbukti berguna dalam beberapa situasi (misalnya, ketika menerapkan versi yang sedikit diretas (bertentangan dengan enkapsulasi) dari pola desain pengunjung )

Berikut adalah contoh sederhana tentang cara kerja kelebihan fungsi berfungsi:

__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
sumber
Orang akan berpikir bahwa petunjuk ini, dikombinasikan dengan metode swizzling, memang bisa mengarah pada metode "kelebihan beban" ... Mengapa orang perlu, dengan iddan isKindOfClass:pada saat pembuangan, adalah cerita yang berbeda ...
Alex Gray
1
@ alexgray Saya mengerti maksud Anda, iddan isKindOfClass:membahas sebagian besar skenario praktis. Salah satu alasan Anda mungkin lebih suka kelebihan beban, adalah pemilihan otomatis dari jenis yang paling spesifik dipenuhi, yang akan menyebabkan overhead kecil untuk mempertahankan dengan pengecekan tipe eksplisit.
Chris Hatton
1
Dokumentasi dentang secara eksplisit mengatakan bahwa yang dilakukannya adalah menyediakan mangling nama C ++ untuk C. Dan itu pada dasarnya hanya kompiler yang secara otomatis melakukan di belakang layar apa yang dilakukan seseorang di Objective-C dengan memberikan metode nama yang berbeda dengan mencakup (dalam bentuk yang lebih panjang) tipe argumen.
Chris Stratton
19

David benar dalam metode overloading yang tidak didukung di Objective-C. Ini mirip dengan PHP dalam pengertian itu. Seperti yang dia tunjukkan, adalah praktik umum untuk mendefinisikan dua atau lebih metode dengan tanda tangan yang berbeda dalam cara dia contoh. Namun, dimungkinkan juga untuk membuat satu metode menggunakan tipe "id". Melalui tipe "id", Anda dapat mengirim objek apa pun (dan primitif apa pun menggunakan kelas NSNumber) ke metode dan kemudian dari dalam metode itu sendiri Anda dapat menguji jenisnya dan melemparkan pengecualian yang sesuai jika perlu. Meskipun ini memiliki hit kinerja kecil, kemungkinan besar akan nominal atau tidak signifikan kecuali Anda sedang memproses data dalam jumlah besar.

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

Ini juga merupakan tempat yang indah untuk mengimplementasikan protokol untuk menegakkan tipe objek, yang dapat dilakukan seperti:

(id<MyProtocol>)object
Ziminji
sumber