2010-03-06 32 views
20

Giao diện c Mục tiêu có thể có nhiều triển khai không? Ví dụ tôi có thể có một giao diện nhưng 2 triển khai một trong những nơi mà tôi sử dụng một mảng hoặc một nơi mà tôi sử dụng một stack..etc để thực hiện nó.Giao diện c Mục tiêu có thể có nhiều hơn một triển khai không?

Nếu bạn gọi nó như thế nào/cú pháp?

+0

Cách sử dụng "Giao thức"? Nó gần gũi hơn với java/C# interfaces.which là những gì tôi muốn? – user48545

Trả lời

25

Objective-C có khái niệm về một Nghị định thư, đó là đặc điểm kỹ thuật của một giao diện. Thông qua các giao thức , Objective-C hỗ trợ đầy đủ nhiều thừa kế đặc tả (nhưng không thực hiện). Vì vậy, một chút nhầm lẫn, cú pháp @interface thực sự định nghĩa lớp (triển khai), chỉ hỗ trợ kế thừa đơn, nhưng có thể chỉ định việc thực hiện nhiều/nhiều thừa kế của các giao thức hoặc thông số kỹ thuật của giao diện. Cuối cùng, điều này rất giống với Java.

Ví dụ:

@protocol SomeInterface 
- (void)interfaceMethod1; 
- (void)interfaceMethod2; 
@end 

@interface SomeClass:NSObject <SomeInterface> 
@end 

@interface AnotherClass:NSObject <SomeInterface> 
@end 

Thể hiện của một trong hai SomeClass hoặc AnotherClass cả tuyên bố rằng họ cung cấp việc thực hiện yêu cầu cho các SomeInterfacegiao thức.

Mục tiêu-C được nhập động và không yêu cầu đối tượng thực sự chỉ định thư được gửi đến nó. Nói cách khác, bạn bừa bãi có thể gọi bất kỳ phương pháp nào bạn muốn trên SomeClass, cho dù nó được quy định tại nó giao diện hoặc bất kỳ giao thức của nó hoặc không (không rằng điều này sẽ nhất thiết là một điều năng suất cao hoặc tích cực để làm).

Vì vậy, tất cả những điều sau đây sẽ biên dịch (mặc dù có cảnh báo) và chạy tốt, mặc dù các thông điệp/phương pháp mà không thực hiện về cơ bản là không có op trong trường hợp này. Objective-C có một quá trình xử lý/chuyển tiếp phương thức khá phức tạp (và rất thú vị), hơi vượt quá phạm vi của câu hỏi này.

SomeClass * someObject = [[SomeClass alloc] init; 
[someObject someUnspecifiedMethod]; // Compiles with warning - no op 
[someObject interfaceMethod1]; 

Nếu bạn muốn xác định một cái gì đó mà có thể là bất kỳ lớp (@ interface) gõ nhưng thực hiện một giao diện cụ thể (@protocol), bạn có thể sử dụng một cái gì đó như thế này:

id <SomeInterface> obj; 

obj có thể giữ đối tượng SomeClass hoặc AnotherClass.

+0

Bạn nói đúng ... Tôi đã trả lời câu hỏi "cơ sở" nhiều hơn (và không thực sự là câu hỏi mà OP hỏi) ... sau khi đọc lại, tôi có thể thấy OP có lẽ đang tìm kiếm thứ gì đó phù hợp hơn câu trả lời của bạn/các nhà máy/cụm lớp trừu tượng. – rcw3

3

Bạn có nghĩa là ví dụ như thế này:

@interface MasterViewController : 
    UIViewController <GKPeerPickerControllerDelegate, 
        GKSessionDelegate, 
        UITextFieldDelegate, 
        UITableViewDelegate, 
        AVAudioRecorderDelegate> { 
} 
+0

Hoặc bạn có thực sự có ý nghĩa nhiều hơn một khối @ triển khai/@ kết thúc không? –

+0

Tìm thấy cách này để tìm cách khai báo nhiều đại biểu với việc tạo ra các lớp và triển khai riêng biệt. Điều này làm việc hoàn hảo. Cảm ơn 2 năm sau. –

24

Có lẽ bạn nên thử kiểu Ca cao gọi là Class Cluster. Để bắt đầu sử dụng nó, bạn cần tạo lớp công khai có tên là SomeClass và hai lớp con riêng SomeArrayClassSomeStackClass. Khi bạn cần sử dụng ngăn xếp, hàm tạo lớp công khai của bạn sẽ tạo ra cá thể của SomeStackClass và sẽ trả về nó dưới dạng phiên bản công khai có sẵn của SomeClass.

+1

Đây chính là mẫu bạn muốn sử dụng. – bbum

+0

Làm thế nào về việc sử dụng "Giao thức"? Nó gần gũi hơn với java/C# interfaces.which là những gì tôi muốn. – user48545

20

(Nếu bạn bỏ phiếu này, vui lòng cho Roman phiếu bầu - câu trả lời của anh ấy trước tiên là chính xác, chỉ thiếu một ví dụ).

Bạn đang nói về một số Class Cluster. Ví dụ: xem lớp NSString.

Có NSString:

@interface NSString : NSObject 

Và NSMutableString:

@interface NSMutableString : NSString 

Cả hai trong số đó tuyên bố một bộ rất nhỏ của phương pháp trong khai lớp lõi của. Nếu bạn đã phân lớp NSString để triển khai lớp chuỗi của riêng bạn, bạn sẽ chỉ cần triển khai các phương pháp cốt lõi đó. Tất cả các phương pháp khác được triển khai trong NSString được thực hiện theo các phương pháp cốt lõi. Và, tương tự như vậy, các phương thức đột biến được thực hiện bằng cách sử dụng các phương thức nguyên thủy được khai báo trong lõi của NSMutableString.

Bây giờ, rõ ràng là việc triển khai tất cả các khả năng đột biến qua - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString (phương pháp một lõi) sẽ không hiệu quả. Do đó, trong thời gian chạy, bạn sẽ lưu ý rằng bạn không bao giờ thực sự có một cá thể của NSString hoặc NSMutableString, nhưng chỉ các trường hợp của các lớp con (thực tế, không phải là các lớp con ... nhưng chúng cũng có thể nằm trong ngữ cảnh của cuộc thảo luận này).

Và các lớp con đó - lớp triển khai được sử dụng trong thời gian chạy - ghi đè hầu hết tất cả các phương pháp NSString và NSMutableString để cung cấp các triển khai tối ưu hóa cao cho các hoạt động cụ thể.

Vì vậy, bạn sẽ làm điều gì đó như:

@interface MyAbstractClass : NSObject 
... declare factory methods here ... 
... declare core methods here ... 
@end 

@interface MyAbstractClass(AdditionalFunctionality) 
... declare convenience here ... 
@end 

Sau đó, trong việc thực hiện, thực hiện tất cả các phương pháp cốt lõi như @throw @"Must use subclass" và tất cả các phương pháp AdditionalFunctionality về các phương pháp cốt lõi.

Điều này có thể hoàn toàn tin - không phải trong một tiêu đề ở tất cả, thậm chí:

@ interface MyStackClass: MyAbstractClass @end

@implementation MyStackClass ... thực hiện các phương pháp cốt lõi và ghi đè lên các phương pháp chức năng bổ sung cần tối ưu hóa ... @end

Lặp lại các loại lớp bổ sung của bạn. Sau đó, thực hiện các phương thức factory trên MyAbstractClass để trả về các cá thể của các lớp con, nếu cần.

Các vấn đề liên quan