Tôi biết Java và bây giờ tôi đang học Objective-C. Chính xác thì sự khác biệt giữa giao diện Java và giao thức Objective-C là gì?
Tôi biết Java và bây giờ tôi đang học Objective-C. Chính xác thì sự khác biệt giữa giao diện Java và giao thức Objective-C là gì?
Câu trả lời:
Trước hết, một chút quan điểm lịch sử về chủ đề này , từ một trong những người tạo ra Java. Tiếp theo, Wikipedia có một phần hữu ích vừa phải về các giao thức Objective-C . Đặc biệt, hãy hiểu rằng Objective-C hỗ trợ cả giao thức chính thức (được khai báo rõ ràng bằng @protocol
từ khóa, tương đương với giao diện Java) và giao thức không chính thức (chỉ một hoặc nhiều phương thức được thực hiện bởi một lớp, có thể được phát hiện thông qua phản chiếu).
Nếu bạn áp dụng một giao thức chính thức (thuật ngữ Objective-C cho "triển khai giao diện"), trình biên dịch sẽ phát ra cảnh báo cho các phương thức chưa hoàn thành, giống như bạn mong đợi trong Java. Không giống như Java (như skaffman đã đề cập), nếu một lớp Objective-C triển khai các phương thức có trong một giao thức chính thức, nó được cho là "tuân theo" giao thức đó, ngay cả khi giao diện của nó không áp dụng nó một cách rõ ràng.Bạn có thể kiểm tra tính tuân thủ của giao thức trong mã (sử dụng -conformsToProtocol:) như sau:
if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
...
}
LƯU Ý: Tài liệu của Apple cho biết:
"Phương pháp này chỉ xác định sự tuân thủ dựa trên các khai báo chính thức trong tệp tiêu đề, như được minh họa ở trên. Nó không kiểm tra xem liệu các phương thức được khai báo trong giao thức có thực sự được triển khai hay không - đó là trách nhiệm của lập trình viên."
Kể từ Objective-C 2.0 (trong OS X 10.5 "Leopard" và iOS), các giao thức chính thức hiện có thể xác định các phương thức tùy chọn và một lớp tuân theo một giao thức miễn là nó triển khai tất cả các phương thức được yêu cầu. Bạn có thể sử dụng @required
(mặc định) và @optional
từ khóa để chuyển đổi xem các khai báo phương thức theo sau phải hoặc có thể được triển khai để phù hợp với giao thức hay không. (Xem phần hướng dẫn Ngôn ngữ lập trình Objective-C 2.0 của Apple thảo luận về các phương pháp giao thức tùy chọn .)
Các phương pháp giao thức tùy chọn mở ra rất nhiều sự linh hoạt cho các nhà phát triển, đặc biệt là để triển khai các đại biểu và người nghe . Thay vì mở rộng một cái gì đó như MouseInputAdapter (điều này có thể gây khó chịu, vì Java cũng là đơn kế thừa) hoặc triển khai nhiều phương thức trống rỗng, vô nghĩa, bạn có thể áp dụng một giao thức và chỉ triển khai các phương thức tùy chọn mà bạn quan tâm. Với mẫu này, người gọi sẽ kiểm tra xem phương thức có được triển khai hay không trước khi gọi nó (sử dụng -respondsToSelector ) như sau:
if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
[myObject fillArray:anArray withObject:foo];
...
}
Nếu chi phí phản chiếu trở thành vấn đề, bạn luôn có thể lưu kết quả boolean vào bộ nhớ cache để sử dụng lại , nhưng không muốn tối ưu hóa quá sớm. :-)
-conformsToProtocol:
sẽ chỉ trả về CÓ nếu lớp chấp nhận giao thức một cách rõ ràng. Bạn thậm chí đã thử nó?
-conformsToProtocol:
thực sự yêu cầu rằng lớp (hoặc tổ tiên) chính thức tuyên bố rằng nó chấp nhận giao thức. Không chắc chắn làm thế nào tôi đã sai điều này, cảm ơn đã sửa chữa!
Chúng gần như giống hệt nhau. Tuy nhiên, một điều khiến tôi chú ý, đó là trừ khi bạn tuyên bố rõ ràng rằng một giao thức C mục tiêu cũng triển khai NSObject, các tham chiếu đến giao thức đó không có quyền truy cập vào các phương thức mà NSObject khai báo (dù sao cũng không có cảnh báo trình biên dịch). Với java, bạn có thể tham chiếu đến một giao diện và vẫn gọi toString (), v.v. trên đó.
ví dụ
Mục tiêu C:
@protocol MyProtocol
// Protocol definition
@end
id <MyProtocol> myProtocol;
[myProtocol retain] // Compiler warning
Java:
public interface MyInterface {
// interface definition
}
MyInterface myInterface;
myInterface.toString(); // Works fine.
Mục tiêu C (cố định):
@protocol MyProtocol <NSObject>
// Protocol definition
@end
id <MyProtocol> myProtocol;
[myProtocol retain] // No Warning