Objective-C'de yöntem aşırı yükleme?


131

Bildiğim kadarıyla, Objective-C yöntem aşırı yüklemesini desteklemiyor. Bunun Objective-C'de alternatifi ne olabilir? Yoksa her zaman farklı bir yöntem adı mı kullanmalıyım?

Yanıtlar:


193

Doğru, amaç-C yöntem aşırı yüklemesini desteklemez, bu nedenle farklı yöntem adları kullanmanız gerekir.

Bununla birlikte, "yöntem adı" nın, yöntem imzası anahtar sözcüklerini (":" s'den önce gelen parametre adları) içerdiğine dikkat edin, bu nedenle, ikisi de "writeToFile" ile başlamış olsalar bile , aşağıdakiler iki farklı yöntemdir:

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

(iki yöntemin adı "writeToFile: fromInt:" ve "writeToFile: fromString:" şeklindedir).


4
@RaheelSadiq Aşırı yükleme değildir çünkü yöntem isimleri (ObjC'de: 'seçiciler') farklıdır. Farklı olduğu için ikisi de 'aşırı yüklenmiş' sayılmaz. WriteToFile: from: iki kez tanımlandıysa, yalnızca parametre türleri farklıysa, bu aşırı yükleme olur. Yine de belirtildiği gibi, bu, Java ve şimdi Swift dahil diğer dillerde olduğu gibi ObjC'de desteklenmiyor.
Chris Hatton

Yalnızca parametre adlarının kendisi değil, iki nokta üst üste bile yöntem adının bir parçasıdır, böylece - (void) writeToFile: (NSString *) yol: (int) anInt; ve - (void) writeToFile: (NSString ) yol: (NSString ) aString; ayrıca farklı yöntemlerdir.
Kaiserludi

22

Objective-C, yöntem aşırı yüklemesini desteklemese bile , Clang + LLVM'nin C için işlev aşırı yüklemesini desteklediğini belirtmekte fayda var , tam olarak aradığınız şey olmasa da, bazı durumlarda yararlı olabilir (örneğin, uygulayan biraz kesmek (encapsulation aykırı) versiyonunu ait ziyaretçi tasarım deseni )

Fonksiyon aşırı yüklemesinin nasıl çalıştığına dair basit bir örnek:

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

Bu ipucunun metot karıştırmayla birleştiğinde, gerçekten de "aşırı yüklenebilir" yöntemlere yol açabileceği düşünülebilir ... Yine de, neden kişinin elinin altında idve onun isKindOfClass:emrinde olması gerektiği farklı bir hikaye ...
Alex Gray

1
@alexgray Ne demek istediğini anlıyorum idve isKindOfClass:en pratik senaryoları anlatıyorum . Aşırı yüklemeyi tercih etmenizin bir nedeni, en spesifik türün otomatik olarak seçilmesidir; bu, açık tür kontrolüyle sürdürülmesi gereken küçük bir ek yüke neden olur.
Chris Hatton

1
Clang dokümantasyonu açıkça yaptığı şeyin C için C ++ ismini karıştırmak olduğunu açıkça söylüyor. Ve bu temelde derleyicinin otomatik olarak sahne arkasında bir kişinin Objective-C'de yaptığı şeyi kapsayarak (daha uzun biçimde) farklı yöntem isimleri vererek yapıyor. argüman türleri.
Chris Stratton

19

David, yöntem aşırı yüklemesinin Objective-C'de desteklenmediği konusunda haklıdır. Bu anlamda PHP'ye benzer. Kendisinin de belirttiği gibi, örneklediği şekilde iki veya daha fazla yöntemi farklı imzalarla tanımlamak yaygın bir uygulamadır. Bununla birlikte, "id" tipini kullanarak bir yöntem oluşturmak da mümkündür. "İd" türü aracılığıyla, herhangi bir nesneyi (ve NSNumber sınıfını kullanan herhangi bir ilkeli) yönteme gönderebilir ve ardından yöntemin kendi içinden türünü test edebilir ve gerekirse uygun istisnayı atabilirsiniz. Bunun küçük bir performans darbesi olmasına rağmen, büyük miktarlarda veri işlemediğiniz sürece büyük olasılıkla nominal veya önemsiz olacaktır.

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

Bu aynı zamanda, nesne türünü zorlamak için bir protokol uygulamak için güzel bir yerdir, bu şu şekilde yapılabilir:

(id<MyProtocol>)object
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.