ฉันรู้จัก Java และตอนนี้ฉันเรียน Objective-C อะไรคือความแตกต่างระหว่างอินเตอร์เฟส Java และโปรโตคอล Objective-C
ฉันรู้จัก Java และตอนนี้ฉันเรียน Objective-C อะไรคือความแตกต่างระหว่างอินเตอร์เฟส Java และโปรโตคอล Objective-C
คำตอบ:
ก่อนอื่นให้ดูมุมมองทางประวัติศาสตร์เล็กน้อยในหัวข้อนี้จากหนึ่งในผู้สร้าง Java ถัดไป, วิกิพีเดียมีประโยชน์ในระดับปานกลางส่วนบนโปรโตคอล Objective-C โดยเฉพาะอย่างยิ่งโปรดเข้าใจว่า Objective-C สนับสนุนทั้งโปรโตคอลที่เป็นทางการ (ซึ่งประกาศอย่างชัดเจนด้วย@protocol
คีย์เวิร์ดเทียบเท่ากับอินเทอร์เฟซ Java) และโปรโตคอลแบบไม่เป็นทางการ (เพียงหนึ่งวิธีหรือมากกว่าที่ใช้ในคลาสซึ่งสามารถค้นพบได้ผ่านการสะท้อนกลับ)
หากคุณใช้โปรโตคอลแบบเป็นทางการ (คำศัพท์ Objective-C สำหรับ "ใช้งานอินเทอร์เฟซ") คอมไพเลอร์จะส่งคำเตือนสำหรับวิธีการที่ไม่ได้ใช้งานเช่นเดียวกับที่คุณคาดหวังใน Java ซึ่งแตกต่างจาก Java (ตามที่skaffmanกล่าวถึง) หากคลาส Objective-C ใช้เมธอดที่มีอยู่ในโปรโตคอลที่เป็นทางการจะมีการกล่าวว่า "สอดคล้อง" กับโปรโตคอลนั้นแม้ว่าอินเทอร์เฟซจะไม่ได้นำมาใช้อย่างชัดเจนก็ตามคุณสามารถทดสอบความสอดคล้องของโปรโตคอลในโค้ด (โดยใช้-conformsToProtocol :) ดังนี้ :
if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
...
}
หมายเหตุ: สถานะเอกสารของ Apple :
"วิธีนี้กำหนดความสอดคล้องโดยอาศัยการประกาศอย่างเป็นทางการในไฟล์ส่วนหัวเท่านั้นดังที่แสดงไว้ด้านบนวิธีนี้ไม่ได้ตรวจสอบว่ามีการนำวิธีการที่ประกาศในโปรโตคอลไปใช้จริงหรือไม่นั่นเป็นความรับผิดชอบของโปรแกรมเมอร์"
สำหรับ Objective-C 2.0 (ใน OS X 10.5 "Leopard" และ iOS) ตอนนี้โปรโตคอลที่เป็นทางการสามารถกำหนดวิธีการเสริมได้และคลาสจะเป็นไปตามโปรโตคอลตราบใดที่ใช้วิธีการที่จำเป็นทั้งหมด คุณสามารถใช้@required
(ค่าเริ่มต้น) และ@optional
คำสำคัญเพื่อสลับว่าการประกาศวิธีการที่ตามมาจะต้องหรืออาจนำไปใช้เพื่อให้สอดคล้องกับโปรโตคอลหรือไม่ (ดูส่วนของคู่มือภาษาโปรแกรม Objective-C 2.0ของ Apple ที่กล่าวถึงวิธีโปรโตคอลเสริม )
วิธีการเลือกโครงการเปิดขึ้นมีความยืดหยุ่นมากให้กับนักพัฒนาโดยเฉพาะอย่างยิ่งสำหรับการดำเนินการที่ได้รับมอบหมายและผู้ฟัง แทนที่จะขยายบางอย่างเช่นMouseInputAdapter (ซึ่งอาจสร้างความรำคาญได้เนื่องจาก Java ยังเป็นมรดกเดียว) หรือใช้วิธีการที่ไม่มีจุดหมายและว่างเปล่าจำนวนมากคุณสามารถใช้โปรโตคอลและใช้เฉพาะวิธีการเสริมที่คุณสนใจ ด้วยรูปแบบนี้ผู้โทรจะตรวจสอบว่ามีการนำเมธอดไปใช้ก่อนที่จะเรียกใช้ (โดยใช้-respondsToSelector ) ดังนี้:
if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
[myObject fillArray:anArray withObject:foo];
...
}
หากค่าเหนือศีรษะของการสะท้อนกลายเป็นปัญหาคุณสามารถแคชผลลัพธ์บูลีนเพื่อนำกลับมาใช้ใหม่ได้ตลอดเวลา แต่ต่อต้านการกระตุ้นให้ปรับให้เหมาะสมก่อนเวลาอันควร :-)
-conformsToProtocol:
จะส่งคืน YES ก็ต่อเมื่อชั้นเรียนใช้โปรโตคอลอย่างชัดเจน คุณเคยลองหรือยัง?
-conformsToProtocol:
แน่นอนว่าชั้นเรียน (หรือบรรพบุรุษ) ประกาศอย่างเป็นทางการว่าใช้โปรโตคอลหรือไม่ ไม่แน่ใจว่าฉันทำผิดอย่างไรขอบคุณสำหรับการแก้ไข!
เกือบจะเหมือนกัน อย่างไรก็ตามสิ่งหนึ่งที่ทำให้ฉันติดใจก็คือเว้นแต่คุณจะประกาศอย่างชัดเจนว่าโปรโตคอล C วัตถุประสงค์ยังใช้ NSObject การอ้างอิงถึงโปรโตคอลนั้นจะไม่สามารถเข้าถึงวิธีการที่ NSObject ประกาศได้ (โดยไม่มีคำเตือนของคอมไพเลอร์อยู่แล้ว) ด้วย java คุณสามารถมีการอ้างอิงถึงอินเทอร์เฟซและยังคงเรียก toString () เป็นต้น
เช่น
วัตถุประสงค์ 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.
วัตถุประสงค์ C (คงที่):
@protocol MyProtocol <NSObject>
// Protocol definition
@end
id <MyProtocol> myProtocol;
[myProtocol retain] // No Warning