Java'yı biliyorum ve şimdi Objective-C'yi öğreniyorum. Java arayüzleri ile Objective-C protokolleri arasındaki farklar tam olarak nedir?
Java'yı biliyorum ve şimdi Objective-C'yi öğreniyorum. Java arayüzleri ile Objective-C protokolleri arasındaki farklar tam olarak nedir?
Yanıtlar:
Öncelikle , Java'nın yaratıcılarından birinden konu hakkında biraz tarihsel bir bakış açısı . Daha sonra, Wikipedia'nın Objective-C protokolleri hakkında oldukça yararlı bir bölümü var . Özellikle, Objective-C'nin hem biçimsel protokolleri ( @protocolanahtar sözcükle açıkça bildirilen , bir Java arayüzünün eşdeğeri) hem de resmi olmayan protokolleri (yansıma yoluyla keşfedilebilen bir sınıf tarafından uygulanan yalnızca bir veya daha fazla yöntem ) desteklediğini anlayın .
Resmi bir protokol kullanırsanız ("arabirim uygulamak" için Objective-C terminolojisi), derleyici Java'da beklediğiniz gibi uygulanmayan yöntemler için uyarılar yayınlayacaktır. Java'nın aksine ( skaffman'ın bahsettiği gibi), bir Objective-C sınıfı resmi bir protokolde yer alan yöntemleri uygularsa, arabirimi açıkça benimsemese bile bu protokole "uygun" olduğu söylenir.Protokol uygunluğunu kodda ( -conformsToProtocol kullanarak ) şu şekilde test edebilirsiniz :
if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
...
}
NOT: Apple'ın belgeleri şu şekildedir:
"Bu yöntem, yukarıda gösterildiği gibi, yalnızca başlık dosyalarındaki resmi bildirimler temelinde uygunluğu belirler. Protokolde bildirilen yöntemlerin gerçekten uygulanıp uygulanmadığını kontrol etmez - bu programcının sorumluluğundadır."
Objective-C 2.0'dan itibaren (OS X 10.5 "Leopard" ve iOS'ta), resmi protokoller artık isteğe bağlı yöntemleri tanımlayabilir ve bir sınıf, gerekli tüm yöntemleri uyguladığı sürece bir protokole uyar. Sen kullanabilirsiniz @required(varsayılan) ve @optionalizleyin yöntem bildirimleri olmadığını geçiş için anahtar kelimeler mutlaka ya edebilir uygulanacak protokole uyması için. (Apple'ın Objective-C 2.0 Programlama Dili kılavuzunun isteğe bağlı protokol yöntemlerini tartışan bölümüne bakın .)
İsteğe bağlı protokol yöntemleri, özellikle temsilcilerin ve dinleyicilerin uygulanması için geliştiricilere büyük esneklik sağlar . MouseInputAdapter gibi bir şeyi genişletmek (Java da tek kalıtım olduğu için can sıkıcı olabilir) ya da çok sayıda anlamsız, boş yöntem uygulamak yerine, bir protokol benimseyebilir ve yalnızca ilgilendiğiniz isteğe bağlı yöntemleri uygulayabilirsiniz. Bu desenle, arayan, yöntemin şu şekilde ( -respondsToSelector kullanarak ) çağrılmadan önce uygulanıp uygulanmadığını kontrol eder :
if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
[myObject fillArray:anArray withObject:foo];
...
}
Yansımanın ek yükü bir sorun haline gelirse , boole sonucunu her zaman yeniden kullanım için önbelleğe alabilir , ancak erken optimize etme dürtüsüne direnebilirsiniz. :-)
-conformsToProtocol:yalnızca sınıf açıkça protokolü benimserse EVET döndürür. Hiç denedin mi?
-conformsToProtocol:, gerçekten de sınıfın (veya bir atanın) resmi olarak protokolü benimsediğini beyan etmesini gerektirir. Bunu nasıl yanlış anladığımdan emin değilim, düzeltme için teşekkürler!
Neredeyse aynılar. Bununla birlikte, beni yakalayan tek şey, nesnel bir C protokolünün NSObject'i de uyguladığını açıkça beyan etmediğiniz sürece, bu protokole yapılan referansların NSObject'in bildirdiği yöntemlere erişemeyeceğidir (yine de bir derleyici uyarısı olmadan). Java ile bir arayüze bir referansınız olabilir ve yine de üzerinde toString () vb.
Örneğin
Hedef 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.
Hedef C (sabit):
@protocol MyProtocol <NSObject>
// Protocol definition
@end
id <MyProtocol> myProtocol;
[myProtocol retain] // No Warning