Saya tahu Java, dan sekarang saya belajar Objective-C. Apa sebenarnya perbedaan antara antarmuka Java dan protokol Objective-C?
Saya tahu Java, dan sekarang saya belajar Objective-C. Apa sebenarnya perbedaan antara antarmuka Java dan protokol Objective-C?
Jawaban:
Pertama, sedikit perspektif sejarah tentang topik tersebut , dari salah satu pencipta Jawa. Selanjutnya, Wikipedia memiliki bagian yang cukup membantu tentang protokol Objective-C . Secara khusus, pahami bahwa Objective-C mendukung kedua protokol formal (yang secara eksplisit dideklarasikan dengan @protocol
kata kunci, setara dengan antarmuka Java) dan protokol informal (hanya satu atau lebih metode yang diterapkan oleh kelas, yang dapat ditemukan melalui refleksi).
Jika Anda mengadopsi protokol formal (terminologi Objective-C untuk "mengimplementasikan antarmuka") kompilator akan mengeluarkan peringatan untuk metode yang tidak diimplementasikan, seperti yang Anda harapkan di Java. Tidak seperti Java (seperti yang disebutkan skaffman ), jika kelas Objective-C mengimplementasikan metode yang terdapat dalam protokol formal, ia dikatakan "menyesuaikan" dengan protokol itu, bahkan jika antarmukanya tidak secara eksplisit mengadopsinya.Anda dapat menguji kesesuaian protokol dalam kode (menggunakan -conformsToProtocol :) seperti ini:
if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
...
}
CATATAN: Dokumentasi Apple menyatakan:
"Metode ini menentukan kesesuaian hanya berdasarkan deklarasi formal dalam file header, seperti yang diilustrasikan di atas. Metode ini tidak memeriksa apakah metode yang dideklarasikan dalam protokol benar-benar diterapkan — itu tanggung jawab programmer."
Sejak Objective-C 2.0 (di OS X 10.5 "Leopard" dan iOS), protokol formal sekarang dapat mendefinisikan metode opsional , dan kelas sesuai dengan protokol selama mengimplementasikan semua metode yang diperlukan. Anda dapat menggunakan @required
(default) dan @optional
kata kunci untuk beralih apakah deklarasi metode yang mengikuti harus atau dapat diimplementasikan agar sesuai dengan protokol. (Lihat bagian panduan Bahasa Pemrograman Objective-C 2.0 Apple yang membahas metode protokol opsional .)
Metode protokol opsional membuka banyak fleksibilitas bagi pengembang, terutama untuk mengimplementasikan delegasi dan pendengar . Alih-alih memperluas sesuatu seperti MouseInputAdapter (yang bisa mengganggu, karena Java juga merupakan pewarisan tunggal) atau menerapkan banyak metode kosong dan tidak berguna, Anda dapat mengadopsi protokol dan hanya mengimplementasikan metode opsional yang Anda pedulikan. Dengan pola ini, pemanggil memeriksa apakah metode diimplementasikan sebelum memanggilnya (menggunakan -respondsToSelector ) seperti ini:
if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
[myObject fillArray:anArray withObject:foo];
...
}
Jika overhead refleksi menjadi masalah, Anda selalu dapat menyimpan hasil boolean ke dalam cache untuk digunakan kembali , tetapi menahan keinginan untuk mengoptimalkan sebelum waktunya. :-)
-conformsToProtocol:
hanya akan mengembalikan YA jika kelas secara eksplisit mengadopsi protokol. Apakah kamu sudah mencobanya?
-conformsToProtocol:
memang mengharuskan kelas (atau leluhur) secara resmi menyatakan bahwa ia mengadopsi protokol. Tidak yakin bagaimana saya melakukan kesalahan ini, terima kasih atas koreksinya!
Mereka hampir identik. Namun satu hal yang menarik perhatian saya, adalah bahwa kecuali Anda secara eksplisit menyatakan bahwa protokol C obyektif juga menerapkan NSObject, referensi ke protokol itu tidak mendapatkan akses ke metode yang dideklarasikan NSObject (tanpa peringatan compiler). Dengan java Anda dapat memiliki referensi ke sebuah antarmuka, dan masih memanggil toString () dll.
misalnya
Tujuan C:
@protocol MyProtocol
// Protocol definition
@end
id <MyProtocol> myProtocol;
[myProtocol retain] // Compiler warning
Jawa:
public interface MyInterface {
// interface definition
}
MyInterface myInterface;
myInterface.toString(); // Works fine.
Tujuan C (tetap):
@protocol MyProtocol <NSObject>
// Protocol definition
@end
id <MyProtocol> myProtocol;
[myProtocol retain] // No Warning