Phương thức quá tải trong Objective-C?


131

Theo như hiểu biết của tôi, Objective-C không hỗ trợ quá tải phương thức. Điều gì có thể thay thế cho điều này trong Objective-C? Hay tôi nên luôn luôn sử dụng tên phương thức khác nhau?

Câu trả lời:


193

Đúng, object-C không hỗ trợ nạp chồng phương thức, vì vậy bạn phải sử dụng các tên phương thức khác nhau.

Tuy nhiên, lưu ý rằng "tên phương thức" bao gồm các từ khóa chữ ký phương thức (tên tham số xuất hiện trước dấu ":"), do đó, sau đây là hai phương thức khác nhau , mặc dù cả hai đều bắt đầu "writeToFile":

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

(tên của hai phương thức là "writeToFile: fromInt:" và "writeToFile: fromString:").


4
@RaheelSadiq Không quá tải vì tên phương thức (Trong ObjC: 'bộ chọn') khác nhau. Là khác nhau, không ai được coi là "quá tải". Nếu writeToFile: from: được xác định hai lần, chỉ có các loại tham số là khác nhau, thì điều đó sẽ quá tải. Như đã nói, điều này không được hỗ trợ trong ObjC giống như với các ngôn ngữ khác bao gồm Java và bây giờ là Swift.
Chris Hatton

Không chỉ các tên tham số, mà ngay cả các dấu hai chấm cũng là một phần của tên phương thức, do đó - (void) writeToFile: (NSString *) path: (int) anInt; và - (void) writeToFile: (NSString ) path: (NSString ) aString; cũng là các phương thức khác nhau.
Kaiserludi

22

Nó có thể là đáng nói rằng ngay cả khi Objective-C không hỗ trợ phương pháp quá tải, Clang + LLVM không hỗ trợ chức năng quá tải cho C. Mặc dù không hoàn toàn những gì bạn đang tìm kiếm, nó có thể hữu ích trong một số trường hợp (ví dụ, khi triển khai phiên bản hơi bị hack (đi ngược lại đóng gói) của mẫu thiết kế khách truy cập )

Đây là một ví dụ đơn giản về cách quá tải chức năng hoạt động:

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

Mọi người sẽ nghĩ rằng gợi ý này, kết hợp với phương pháp phồng, thực sự có thể dẫn đến các phương thức "quá tải" ... Tại sao người ta cần, với idisKindOfClass:theo ý mình, mặc dù, lại là một câu chuyện khác ...
Alex Gray

1
@alexgray Tôi thấy quan điểm của bạn, idisKindOfClass:bao quát hầu hết các tình huống thực tế. Một lý do bạn có thể thích quá tải, là lựa chọn tự động loại cụ thể nhất được phục vụ, sẽ phải chịu một chi phí nhỏ để duy trì với việc kiểm tra loại rõ ràng.
Chris Hatton

1
Tài liệu Clang nói rõ ràng rằng những gì nó cung cấp cho việc xáo trộn tên C ++ cho C. Và về cơ bản đó chỉ là trình biên dịch tự động thực hiện phía sau những gì người ta làm trong Objective-C bằng cách đưa ra các tên phương thức khác biệt bằng cách bao gồm (ở dạng dài hơn) các loại đối số.
Chris Stratton

19

David đúng trong trường hợp quá tải phương thức không được hỗ trợ trong Objective-C. Nó tương tự như PHP theo nghĩa đó. Như ông cũng chỉ ra, thông thường là xác định hai hoặc nhiều phương thức với các chữ ký khác nhau theo cách mà ông ví dụ. Tuy nhiên, cũng có thể tạo một phương thức bằng cách sử dụng loại "id". Thông qua loại "id", bạn có thể gửi bất kỳ đối tượng nào (và bất kỳ nguyên thủy nào sử dụng lớp NSNumber) đến phương thức và sau đó từ chính phương thức đó, bạn có thể kiểm tra loại của nó và ném ngoại lệ thích hợp nếu cần. Mặc dù điều này có một hiệu suất nhỏ, rất có thể nó sẽ là danh nghĩa hoặc không đáng kể trừ khi bạn đang xử lý một lượng lớn dữ liệu.

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

Đây cũng là một nơi tuyệt đẹp để thực hiện một giao thức để thực thi loại đối tượng, có thể được thực hiện như vậy:

(id<MyProtocol>)object
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.