ถ้าฉันใช้อินเทอร์เฟซจะเรียกว่าการสืบทอด?


31

ถ้าชั้นเรียนของฉันimplementsมีอินเตอร์เฟซฉันจะบอกได้ไหมว่าฉันกำลังติดตามมรดกอยู่? ฉันรู้ว่าเมื่อเรียนextendsอีกชั้นหนึ่งแล้วมันเป็นมรดก



7
ความคิดเห็นของ Jodrell นั้นผิดปกติ การใช้อินเทอร์เฟซเป็นการรับมรดกแน่นอนและการสืบทอดหนึ่งอินเทอร์เฟซจากอื่นเป็นการสืบทอด เราจะรู้ได้อย่างไร โดยการกำหนดคำที่เราใช้ การสืบทอดเป็นคุณสมบัติที่สมาชิกที่สืบทอดได้ของประเภทหนึ่งเป็นสมาชิกประเภทอื่น โดยนิยามนี้คลาสที่ใช้อินเตอร์เฟสได้รับสืบทอดเมธอดของอินเตอร์เฟสทั้งหมดอย่างชัดเจน เพียงแค่ดูที่คลาสและอินเทอร์เฟซแล้วคุณจะพบว่าในโปรแกรมที่ถูกต้องพวกเขามีสมาชิกเหมือนกัน
Eric Lippert

ฉันไม่ได้ทำเครื่องหมายและทิ้งไว้กับความสับสนมากขึ้น
RajeeV VenkaT

18
สำหรับสิ่งที่คุ้มค่าฉันคิดว่าคุณใช้เวลามากกับคำนิยามที่จะไม่ให้ประโยชน์กับคุณมากนัก ในตอนท้ายของวันเราทุกคนรู้ว่าการใช้อินเทอร์เฟซหมายถึงอะไรและไม่ว่ามันจะถูกพิจารณาว่าเป็น "การสืบทอด" เป็นสิ่งสำคัญสำหรับงานประจำวันของคุณหรือไม่
Robert Harvey

3
ฉัน (ส่วนใหญ่) เห็นด้วยกับโรเบิร์ต ฉันคิดว่ามีคุณค่าที่แท้จริงในการทำความเข้าใจความหมายทางเทคนิคที่แม่นยำของคำศัพท์แสงที่ใช้ในบริบทต่างๆ แต่โรเบิร์ตพูดถูกว่ามันมีประโยชน์มากกว่าที่จะเข้าใจผลกระทบที่เกิดขึ้นจริง! คุณจะใช้การสืบทอดเพื่อทำให้รหัสของคุณปลอดภัยยิ่งขึ้นได้อย่างไร ทดสอบได้มากขึ้น? นำมาใช้ใหม่มากขึ้น? มีความยืดหยุ่นมากขึ้น? และอื่น ๆ การรู้ว่าสมาชิกประเภทฐานเป็นสมาชิกประเภทที่ได้รับนั้นยอดเยี่ยม แต่ก็ยังดีกว่าที่จะรู้วิธีใช้อย่างมีประสิทธิภาพ
Eric Lippert

คำตอบ:


78

UPDATE: ฉันได้แก้ไขคำตอบนี้แล้ว มีการเพิ่มคะแนนดี ๆ ในความคิดเห็นที่สมควรได้รับการโทรออก

ถ้าชั้นเรียนของฉันใช้อินเทอร์เฟซฉันจะบอกได้ไหมว่าฉันกำลังติดตามมรดกอยู่?

ไม่ชัดเจนว่าคุณหมายถึงอะไรโดยการ "ติดตามมรดก" ลองถามคำถามที่แตกต่างกันเล็กน้อย

มรดกคืออะไร

  • เมื่อสมาชิกประเภทหนึ่ง X จะถือว่าเป็นสมาชิกของประเภทอื่น Y, บรรดาสมาชิกของ Y จะสืบทอดมาจาก X
  • มีความสัมพันธ์ที่สืบทอดระหว่างบางชนิด; นั่นคือสำหรับบางประเภท X และ Y เราพูดว่า "Y สืบทอดมาจาก X"

สิ่งเหล่านี้แตกต่างกันเล็กน้อย นั่นเป็นโชคร้ายเพราะมันทำให้เกิดความสับสน

อะไรคือความสับสนที่เกิดขึ้นจากความแตกต่างที่ลึกซึ้งนี้?

ความสับสนอาจเกิดขึ้นเพราะผู้คนคิดว่าการสืบทอดเป็นกลไกในการแบ่งปันรายละเอียดการนำไปปฏิบัติ แม้ว่ามันจะเป็นเช่นกลไกกลไกที่ทำงานได้ด้วยการแบ่งปันสมาชิก สมาชิกเหล่านั้นไม่จำเป็นต้องมีการใช้งาน! อย่างที่เราจะเห็นพวกเขาสามารถเป็นนามธรรม

ฉันเองจะมีความสุขมากขึ้นถ้าข้อกำหนดของ Java และ C # ใช้คำอื่นที่ไม่ใช่ "สืบทอด" เพื่ออธิบายความสัมพันธ์ระหว่างวิธีการอินเตอร์เฟสและคลาสเพื่อหลีกเลี่ยงความสับสนนี้ แต่พวกเขาทำไม่ได้และเราต้องเหตุผลจากข้อกำหนดไม่ได้กับพวกเขา

ใน Java สมาชิกอินเทอร์เฟซที่สืบทอดโดยคลาสที่ใช้งานได้หรือไม่

ใช่บางคน ดูหัวข้อข้อมูลจำเพาะ Java 8.4.8 ซึ่งฉันพูดที่นี่เพื่อความสะดวกของคุณ

คลาส C สืบทอดมาจาก direct superclass และ direct superinterfaces ทั้งหมดเป็นนามธรรมและวิธีการเริ่มต้น m ซึ่งทั้งหมดต่อไปนี้เป็นจริง: [... ]

ถ้าคุณบอกว่าคลาสใช้อินเทอร์เฟซแล้วคลาสจะสืบทอดเมธอด abstract และ default ของอินเตอร์เฟสนั้น (แน่นอนฉันได้ละเว้นเงื่อนไขที่ตามมาดูข้อกำหนดสำหรับรายละเอียดโดยเฉพาะอย่างยิ่งคลาสที่ใช้งานสมาชิกของอินเทอร์เฟซจะไม่ถือว่ามีการสืบทอดสมาชิกนั้นอีกครั้งจะสับสนหรือไม่ใช่)

โดยทั่วไปเราจะพูดใน Java ว่าคลาสสืบทอดมาจากส่วนต่อประสานหรือไม่?

โดยทั่วไปแล้วเราจะบอกว่าคลาสใช้อินเทอร์เฟซ ดังที่ระบุไว้ข้างต้นคลาสอาจสืบทอดสมาชิกจากอินเทอร์เฟซและยังไม่ได้รับการกล่าวเพื่อสืบทอดจากอินเทอร์เฟซ สิ่งที่น่าสับสนใช่

ความแตกต่างที่ลึกซึ้งนี้มีความสำคัญในการทำงานในแต่ละวันหรือไม่?

โดยทั่วไปไม่ได้ การแยกวิเคราะห์สเปคแบบแคบนี้มีประโยชน์สำหรับนักเขียนคอมไพเลอร์มากกว่าผู้พัฒนาธุรกิจ สิ่งสำคัญคือต้องเข้าใจว่าเมื่อใดที่ต้องใช้อินเทอร์เฟซมากกว่าที่จะได้คำจำกัดความที่แม่นยำของ "การสืบทอดจาก"


4
ฉันไม่สามารถโต้แย้งด้วยการอ้างอิงแบบบัญญัติ เมื่อข้อกำหนดแตกต่างกันอย่างที่พวกเขาจำเป็นต้องทำคำง่าย ๆ กลายเป็นเกินความหมายและคลุมเครือนอกบริบท คำถามถูกติดแท็กด้วยjavaดังนั้นนี่คือคำตอบที่ถูกต้องเว้นแต่ว่า OP หมายถึงjava:-) อื่น ๆ
Jodrell

5
แม้ว่าคำถามจะถูกแท็กด้วย Java แต่ฉันพบว่ามีปัญหาในการอ้างอิงข้อกำหนดภาษาสำหรับคำทั่วไป หลายภาษามีอินเทอร์เฟซและข้อกำหนดภาษาของพวกเขาอาจใช้คำอื่นดังนั้นการใช้คำเฉพาะ Java อาจสับสนเมื่อพูดคุยกับนักพัฒนาที่ใช้ X-Lang
โธมัสโอเวนส์

5
@ThomasOwens: ฉันยอมรับว่าสถานการณ์นี้เป็นเรื่องปกติและฉันไม่เห็นด้วยกับข้อสรุปของคุณ วิธีการแก้ปัญหาการสื่อสารที่คุณอธิบายเป็นความรู้แก่ทุกคนที่เกี่ยวข้องกับการมีความหมายที่ถูกต้องของคำในบริบทที่เกี่ยวข้อง ข้อมูลจำเพาะมีอยู่เพื่อให้ความคมชัดนี้ ใช้มัน!
Eric Lippert

5
ทำไมคุณสมบัติภาษาจาวาจะได้รับการพูดครั้งสุดท้ายที่นี่? ข้อกำหนดทางภาษามักอ้างสิทธิ์ในสิ่งที่ "ผู้พัฒนาร่วมกัน" ไม่เห็นด้วยเกี่ยวกับคำศัพท์
Benjamin Gruenbaum

5
@BenjaminGruenbaum: ฉันไม่รู้ นักพัฒนาเหล่านั้นผิดและพวกเขามักจะใช้เวลาในการ "ให้ความรู้" แก่ผู้อื่นเกี่ยวกับความเชื่อที่ผิดของพวกเขา คุณจะไม่เชื่อว่าจำนวนหนังสือภาษาการเขียนโปรแกรมที่ฉันต้องแก้ไขเพราะผู้เขียนมีความเชื่อที่บ้าคลั่งอย่างสมบูรณ์เกี่ยวกับ VB, C #, JavaScript และอื่น ๆ ที่ไม่ถูกต้อง (จอนสกีตไม่ได้ในหมู่พวกเขา; C # ในความลึกที่ถูกต้องตั้งแต่เริ่มต้นไม่เคยมีฉันได้แสดงความคิดเห็นไม่กี่ดังนั้นหนังสือและยังคงอากาศจ่าย!.)
เอริค Lippert

26

การสืบทอดหมายถึงการเขียนคลาสย่อยใหม่สำหรับซูเปอร์คลาส การเขียนคลาสใหม่กับอินเตอร์เฟสกำลังใช้อินเตอร์เฟสนั้น (และการเขียนอินเทอร์เฟซใหม่ที่ใช้แบบเก่านั้นเป็นการขยายส่วนต่อประสานนั้น)

เพียงคำที่ถูกต้องที่ใช้กับทั้งสามเป็นไปได้ที่จะSubtyping ไม่ใช่ทุกประเภทย่อยเป็นประเภทย่อย


1
หนังสือ GoFดูเหมือนจะพิจารณาคำที่เหมาะสมในการถ่ายทอดอินเตอร์เฟซเพื่ออธิบาย subtyping (มาตรา 1.6 Class กับ Interface Inheritance)
gnat

"ฉันเคยเข้าร่วมการประชุมกลุ่มผู้ใช้ Java ที่ James Gosling (นักประดิษฐ์ของ Java) เป็นผู้บรรยายในช่วงถามตอบที่น่าจดจำมีคนถามเขาว่า:" ถ้าคุณสามารถทำจาวาอีกครั้งคุณจะเปลี่ยนอะไร? "" ออกจากคลาส "เขาตอบเขาอธิบายว่าปัญหาแท้จริงไม่ใช่คลาสต่อ se แต่เป็นการใช้งานการสืบทอด (การขยายความสัมพันธ์) การสืบทอดส่วนติดต่อ (ความสัมพันธ์ของการดำเนินการ) เป็นสิ่งที่ดีกว่าคุณควรหลีกเลี่ยงการรับมรดกการนำไปปฏิบัติ javaworld.com/article/2073649/core-java/…
ricardoramos

1

ด้วยคลาสย่อยคุณ

  • สถานะสืบทอดของ superclass (ตัวแปรอินสแตนซ์ทั้งหมดไม่ว่าคุณจะเห็นหรือไม่ก็ตาม)
  • สืบทอดการใช้งานจริง (วิธีที่ไม่ใช่นามธรรมทั้งหมด)

ด้วยส่วนต่อประสานคุณเติมเต็มสัญญาโดยใช้วิธีการที่ประกาศไว้

นั่นเป็นวิธีคลาสสิคในการดู ขณะนี้มีJava 8อินเตอร์เฟสกลายเป็นส่วนผสม:

  • คุณยังคงไม่สืบทอดสถานะ (เนื่องจากอินเตอร์เฟสยังไม่มีตัวแปรอินสแตนซ์)
  • ตอนนี้คุณสามารถสืบทอดการใช้งานเริ่มต้นจากอินเทอร์เฟซ

การใช้อินเทอร์เฟซที่มีวิธีการทั้งหมดที่มีการใช้งานเริ่มต้นยังคงนับเป็น 'ใช้' หรือมากกว่าส่วนขยาย? ฉันไม่สามารถบอกได้ เนื่องจากกรณีนี้ค่อนข้างไกล (จริง ๆ แล้วเปิดใช้งานหลายมรดกไร้สัญชาติ) ฉันยังคงใช้ 'มรดก' กับคลาสย่อยเท่านั้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.