กลับไปหน้าบทความ

อ่าน 5 นาที

การสืบทอดทางพันธุกรรมหลายทาง

การสืบทอดแบบหลายทาง (Multiple inheritance) เป็นคุณลักษณะของ ภาษาการเขียน โปรแกรมเชิง วัตถุ บางภาษา ซึ่งวัตถุหรือ คลาส สามารถ สืบทอด คุณลักษณะจากวัตถุหรือ คลาส...

การสืบทอดทางพันธุกรรมหลายทาง

การสืบทอดแบบหลายทาง (Multiple inheritance)เป็นคุณลักษณะของภาษาการเขียนโปรแกรมเชิงวัตถุ บางภาษา ซึ่งวัตถุหรือคลาสสามารถสืบทอด คุณลักษณะจากวัตถุหรือ คลาสแม่ได้มากกว่าหนึ่งรายการซึ่งแตกต่างจากการสืบทอดแบบทางเดียว (Single inheritance) ที่วัตถุหรือคลาสสามารถสืบทอดได้จากวัตถุหรือคลาสเฉพาะเพียงหนึ่งเดียวเท่านั้น

การสืบทอดแบบหลายทางเป็นประเด็นถกเถียงกันมานานหลายปี[ 1 ] [ 2 ]โดยฝ่ายคัดค้านชี้ให้เห็นถึงความซับซ้อนและความกำกวมที่เพิ่มขึ้นในสถานการณ์ต่างๆ เช่น "ปัญหาเพชร" ซึ่งอาจมีความกำกวมว่าคุณลักษณะเฉพาะนั้นสืบทอดมาจากคลาสแม่ใด หากมีคลาสแม่มากกว่าหนึ่งคลาสที่ใช้งานคุณลักษณะดังกล่าว ปัญหานี้สามารถแก้ไขได้หลายวิธี รวมถึงการใช้การสืบทอดเสมือน [ 3 ] นอกจาก นี้ยังมีการเสนอ วิธีการสร้างวัตถุ แบบอื่น ที่ไม่ขึ้นอยู่กับการสืบทอด เช่นมิกซ์อินและคุณลักษณะเพื่อแก้ไขความกำกวมดังกล่าว

รายละเอียด

ในการเขียนโปรแกรมเชิงวัตถุ (OOP) การสืบทอดหมายถึงความสัมพันธ์ระหว่างสองคลาส โดยที่คลาสหนึ่ง ( คลาส ลูก ) จะสืบทอด (หรือสืบทอดจากหรือขยาย ) คลาส แม่คลาสลูกจะสืบทอดเมธอดและแอตทริบิวต์จากคลาสแม่ ทำให้สามารถใช้งานร่วมกันได้ ตัวอย่างเช่น เราอาจสร้างคลาสตัวแปรMammalที่มีคุณสมบัติ เช่น การกิน การสืบพันธุ์ เป็นต้น จากนั้นกำหนดคลาสลูกCatที่สืบทอดคุณสมบัติเหล่านั้นโดยไม่ต้องเขียนโปรแกรมเพิ่มเติมอย่างชัดเจน ในขณะเดียวกันก็เพิ่มคุณสมบัติใหม่ๆ เช่น การไล่ จับ หนู

การสืบทอดแบบหลายทางช่วยให้นักเขียนโปรแกรมสามารถใช้ลำดับชั้นที่ตั้งฉากกันโดยสิ้นเชิงมากกว่าหนึ่งลำดับชั้นพร้อมกันได้ เช่น การอนุญาตCatให้ขยายคลาสCartoonCharacterและPetเข้าถึงMammalคุณสมบัติจากภายในคลาสเหล่านั้นทั้งหมดได้

การนำไปใช้

ภาษาที่รองรับการสืบทอดแบบหลายทาง ได้แก่C++ , Common Lisp (ผ่านCommon Lisp Object System (CLOS)), EuLisp (ผ่าน The EuLisp Object System TELOS), Curl , Dylan , Eiffel , Logtalk , Object REXX , Scala (ผ่านการใช้ คลาส mixin ), OCaml , Perl , POP-11 , Python , R , RakuและTcl (ในตัวตั้งแต่เวอร์ชัน 8.6 หรือผ่าน Incremental Tcl ( Incr Tcl ) ในเวอร์ชันก่อนหน้า[ 4 ] [ 5 ] )

ระบบรันไทม์ IBM System Object Model (SOM) รองรับการสืบทอดแบบหลายทาง และภาษาโปรแกรมใดๆ ที่กำหนดเป้าหมายเป็น SOM สามารถสร้างคลาส SOM ใหม่ที่สืบทอดมาจากฐานหลายฐานได้

ภาษาโปรแกรมเชิงวัตถุบางภาษา เช่นSwift , Java , Fortran (ตั้งแต่เวอร์ชันปรับปรุงปี 2003) , C#และRubyใช้การสืบทอดแบบเดี่ยวแม้ว่าโปรโตคอลหรืออินเทอร์เฟซจะให้ฟังก์ชันการทำงานบางส่วนของการสืบทอดแบบหลายทางที่แท้จริงก็ตาม

PHPใช้คลาส Traitsเพื่อสืบทอดการใช้งานเมธอดเฉพาะ ในขณะที่Rubyใช้โมดูลเพื่อสืบทอดเมธอดหลายๆ เมธอด

ปัญหาเพชร

แผนภาพการสืบทอดคลาสรูปเพชร

ปัญหาเพชร ” (บางครั้งเรียกว่า “เพชรมรณะ” [ 6 ] ) เป็นความกำกวมที่เกิดขึ้นเมื่อคลาส B และ C สองคลาสสืบทอดมาจาก A และคลาส D สืบทอดมาจากทั้ง B และ C หากมีเมธอดใน A ที่ B และ C เขียนทับและ D ไม่ได้เขียนทับเมธอดนั้น D จะสืบทอดเมธอดเวอร์ชันใด: เวอร์ชันของ B หรือเวอร์ชันของ C?

ตัวอย่างเช่น ในบริบทของการพัฒนาซอฟต์แวร์GUI คลาสหนึ่งอาจสืบทอดมาจากทั้งคลาส(สำหรับรูปลักษณ์) และคลาส(สำหรับฟังก์ชันการทำงาน/การจัดการอินพุต) และทั้งคลาสและต่างก็สืบทอดมาจากคลาส ทีนี้ ถ้ามีเมธอดถูกเรียกใช้สำหรับอ็อบเจ็กต์ และไม่มีเมธอดดังกล่าวในคลาส แต่มีเมธอดที่ถูกเขียนทับใน คลาส หรือ(หรือทั้งสองคลาส) สุดท้ายแล้วควรเรียกใช้เมธอดใด? ButtonRectangleClickableRectangleClickableObjectequalsButtonButtonequalsRectangleClickable

เรียกปัญหานี้ว่า "ปัญหาเพชร" เนื่องจากรูปร่างของแผนภาพการสืบทอดคลาสในสถานการณ์นี้ ในกรณีนี้ คลาส A อยู่ด้านบน คลาส B และ C อยู่แยกกันด้านล่าง และคลาส D เชื่อมต่อทั้งสองเข้าด้วยกันที่ด้านล่างเพื่อสร้างรูปร่างคล้ายเพชร

การบรรเทา

แต่ละภาษามีวิธีจัดการกับปัญหาการสืบทอดซ้ำซ้อนที่แตกต่างกันออกไป

  • C# (ตั้งแต่ C# 8.0) อนุญาตให้มีการใช้งานเมธอดเริ่มต้นของอินเทอร์เฟซ ซึ่งทำให้คลาสAที่ใช้งานอินเทอร์เฟซIaและIbมีเมธอดที่คล้ายกันซึ่งมีการใช้งานเริ่มต้น มีเมธอดที่ "สืบทอด" สองเมธอดที่มีลายเซ็นเดียวกัน ทำให้เกิดปัญหาไดมอนด์ วิธีแก้ปัญหานี้คือการกำหนดAให้ต้องใช้งานเมธอดนั้นเอง ซึ่งจะช่วยขจัดความกำกวม หรือบังคับให้ผู้เรียกใช้ต้องแปลงAวัตถุไปยังอินเทอร์เฟซที่เหมาะสมก่อนเพื่อใช้การใช้งานเริ่มต้นของเมธอดนั้น (เช่น((Ia) aInstance).Method();)
  • โดยค่าเริ่มต้น C++จะพิจารณาเส้นทางการสืบทอดแต่ละเส้นทางแยกกัน ดังนั้น เมื่อพิจารณาปัญหาไดมอนด์Dอ็อบเจ็กต์หนึ่งจะประกอบด้วยAอ็อบเจ็กต์สองตัวที่แยกจากกัน และการใช้Aสมาชิกของอ็อบเจ็กต์นั้นจะต้องระบุคุณสมบัติให้ถูกต้อง หากการสืบทอดจากAไปยังBและการสืบทอดจากAไปCยัง ถูกทำเครื่องหมาย " virtual" ทั้งคู่ (เช่น " class B : virtual public A") C++ จะดูแลเป็นพิเศษโดยการสร้างAอ็อบเจ็กต์เพียงตัวเดียว และการใช้Aสมาชิกของอ็อบเจ็กต์นั้นจะทำงานได้อย่างถูกต้อง หาก มีการผสม การสืบทอดเสมือนและการสืบทอดแบบไม่เสมือน จะมีอ็อบเจ็กต์เสมือนหนึ่งตัวAและอ็อบเจ็กต์แบบไม่เสมือนหนึ่งตัวAสำหรับแต่ละเส้นทางการสืบทอดแบบไม่เสมือนไปยังAC++ กำหนดให้ระบุอย่างชัดเจนว่าคลาสแม่ใดที่เรียกใช้คุณสมบัติที่จะใช้ เช่นWorker::Human.ageC++ ไม่รองรับการสืบทอดซ้ำอย่างชัดเจน เนื่องจากจะไม่มีวิธีใดที่จะระบุคลาสแม่ที่จะใช้ได้ (เช่น มีคลาสปรากฏมากกว่าหนึ่งครั้งในรายการการสืบทอดเดียว [ class Dog : public Animal, Animal]) C++ ยังอนุญาตให้สร้างอินสแตนซ์เดียวของคลาสหลายคลาสผ่านกลไกการสืบทอดเสมือน (เช่นWorker::HumanและMusician::Humanจะอ้างอิงถึงอ็อบเจ็กต์เดียวกัน)
  • Common Lisp CLOSพยายามที่จะให้ทั้งพฤติกรรมเริ่มต้นที่สมเหตุสมผลและความสามารถในการเปลี่ยนแปลงพฤติกรรมนั้นได้ โดยค่าเริ่มต้น เมธอดจะถูกจัดเรียงตามลำดับD,B,C,Aเมื่อเขียน B ก่อน C ในนิยามของคลาส เมธอดที่มีคลาสอาร์กิวเมนต์ที่เฉพาะเจาะจงที่สุดจะถูกเลือก (D>(B,C)>A) จากนั้นจึงเรียงตามลำดับที่คลาสแม่ถูกตั้งชื่อในนิยามของคลาสย่อย (B>C) อย่างไรก็ตาม โปรแกรมเมอร์สามารถเปลี่ยนแปลงลำดับนี้ได้โดยการกำหนดลำดับการแก้ไขเมธอดที่เฉพาะเจาะจงหรือระบุกฎสำหรับการรวมเมธอด สิ่งนี้เรียกว่าการรวมเมธอด ซึ่งสามารถควบคุมได้อย่างสมบูรณ์ MOP ( metaobject protocol) ยังมีวิธีการในการแก้ไขการสืบทอดการเรียกใช้แบบ ไดนามิก การสร้างอินสแตนซ์ของคลาส และกลไกภายในอื่นๆ โดยไม่ส่งผลกระทบต่อเสถียรภาพของระบบ
  • Curlอนุญาตให้สืบทอดคลาสซ้ำได้เฉพาะคลาสที่ถูกระบุว่าเป็นคลาสที่ใช้ร่วมกัน อย่างชัดเจน เท่านั้น คลาสที่ใช้ร่วมกันต้องกำหนดคอนสตรัคเตอร์รอง สำหรับ คอนสตรัคเตอร์ปกติแต่ละตัวในคลาส คอนสตรัคเตอร์ปกติจะถูกเรียกใช้ในครั้งแรกที่สถานะของคลาสที่ใช้ร่วมกันถูกเริ่มต้นผ่านคอนสตรัคเตอร์ของคลาสย่อย และคอนสตรัคเตอร์รองจะถูกเรียกใช้สำหรับคลาสย่อยอื่นๆ ทั้งหมด
  • ในEiffelคุณสมบัติของบรรพบุรุษจะถูกเลือกอย่างชัดเจนด้วยคำสั่ง select และ rename ซึ่งช่วยให้คุณสมบัติของคลาสพื้นฐานสามารถใช้ร่วมกันระหว่างลูกหลานหรือให้แต่ละลูกหลานมีสำเนาแยกต่างหากของคลาสพื้นฐานได้ Eiffel อนุญาตให้รวมหรือแยกคุณสมบัติที่สืบทอดมาจากคลาสบรรพบุรุษได้อย่างชัดเจน Eiffel จะรวมคุณสมบัติเข้าด้วยกันโดยอัตโนมัติหากมีชื่อและการใช้งานเหมือนกัน ผู้เขียนคลาสมีตัวเลือกในการเปลี่ยนชื่อคุณสมบัติที่สืบทอดมาเพื่อแยกออกจากกัน การสืบทอดแบบหลายทางเป็นสิ่งที่เกิดขึ้นบ่อยในการพัฒนา Eiffel ตัวอย่างเช่น คลาสที่มีประสิทธิภาพส่วนใหญ่ในไลบรารี EiffelBase ที่ใช้กันอย่างแพร่หลายของโครงสร้างข้อมูลและอัลกอริทึมมีผู้ปกครองสองคนขึ้นไป[ 7 ]
  • Goป้องกันปัญหาไดมอนด์ในขั้นตอนการคอมไพล์ หากโครงสร้างหนึ่งDฝังโครงสร้างสองโครงสร้างBและCทั้งสองโครงสร้างมีเมธอดF()ซึ่งตรงตามอินเทอร์เฟซ คอมAไพเลอร์จะแจ้งข้อผิดพลาดเกี่ยวกับ "ตัวเลือกที่ไม่ชัดเจน" หากD.F()มีการเรียกใช้เมธอด หรือหากDมีการกำหนดอินสแตนซ์ของให้กับตัวแปรประเภทAและBสามารถCเรียกใช้เมธอดของได้อย่างชัดเจนด้วยD.B.F()หรือD.C.F()
  • Java 8 นำเสนอเมธอดเริ่มต้นบนอินเทอร์เฟซ หากA, BและCเป็นอินเทอร์เฟซBและCแต่ละอินเทอร์เฟซสามารถให้การใช้งานที่แตกต่างกันสำหรับเมธอดนามธรรมของ ซึ่งAทำให้เกิดปัญหาไดมอนด์ คลาสใดคลาสหนึ่งDจะต้องเขียนเมธอดใหม่ (ซึ่งเนื้อหาของเมธอดสามารถส่งต่อการเรียกไปยังการใช้งานของคลาสแม่ได้) มิฉะนั้นความกำกวมจะถูกปฏิเสธเป็นข้อผิดพลาดในการคอมไพล์[ 8 ]ก่อน Java 8 Java ไม่ได้เผชิญกับความเสี่ยงของปัญหาไดมอนด์ เนื่องจากไม่มีเมธอดเริ่มต้นของอินเทอร์เฟซ เวอร์ชัน Java ทั้งหมดจนถึงเวอร์ชันล่าสุดปัจจุบัน 26 ไม่รองรับการสืบทอดแบบหลายทางโดยตรง: คลาสสามารถขยายได้เพียงคลาสเดียว แต่สามารถใช้งานอินเทอร์เฟซหลายรายการด้วยเมธอดเริ่มต้นได้
  • JavaFX Scriptเวอร์ชัน 1.2 อนุญาตให้มีการสืบทอดแบบหลายทางผ่านการใช้mixinในกรณีที่เกิดข้อขัดแย้ง คอมไพเลอร์จะห้ามการใช้งานตัวแปรหรือฟังก์ชันที่ไม่ชัดเจนโดยตรง สมาชิกที่สืบทอดมาแต่ละตัวยังคงสามารถเข้าถึงได้โดยการแปลงวัตถุเป็น mixin ที่ต้องการ(individual as Person).printInfo();เช่น
  • Kotlinอนุญาตให้มีการสืบทอดแบบหลายทางของอินเทอร์เฟซ อย่างไรก็ตาม ในสถานการณ์ปัญหา Diamond นั้น คลาสลูกจะต้องเขียนทับเมธอดที่ทำให้เกิดความขัดแย้งในการสืบทอด และระบุว่าควรใช้การใช้งานของคลาสแม่ใด ตัวอย่างเช่น super<ChosenParentInterface>.someMethod()
  • Logtalkรองรับการสืบทอดแบบหลายชั้นทั้งในส่วนของอินเทอร์เฟซและการใช้งาน ทำให้สามารถประกาศนามแฝงของเมธอดซึ่งให้ทั้งการเปลี่ยนชื่อและการเข้าถึงเมธอดที่อาจถูกปิดกั้นโดยกลไกการแก้ไขข้อขัดแย้งเริ่มต้นได้
  • ในOCamlคลาสแม่จะถูกระบุแยกกันในส่วนเนื้อหาของคำจำกัดความคลาส เมธอด (และแอตทริบิวต์) จะถูกสืบทอดตามลำดับเดียวกัน โดยแต่ละเมธอดที่สืบทอดมาใหม่จะเขียนทับเมธอดที่มีอยู่เดิม OCaml จะเลือกคำจำกัดความที่ตรงกันล่าสุดจากรายการการสืบทอดคลาสเพื่อตัดสินว่าควรใช้การใช้งานเมธอดใดในกรณีที่มีความกำกวม หากต้องการเปลี่ยนแปลงพฤติกรรมเริ่มต้น เพียงแค่ระบุคำจำกัดความของคลาสที่ต้องการลงในการเรียกใช้เมธอด
  • Perlใช้รายการคลาสที่จะสืบทอดเป็นรายการเรียงลำดับ คอมไพเลอร์จะใช้วิธีการแรกที่พบโดยการค้นหาแบบเจาะลึกในรายการคลาสแม่ หรือใช้การเรียงลำดับแบบ C3ของลำดับชั้นคลาส ส่วนขยายต่างๆ ให้รูปแบบการประกอบคลาสทางเลือก ลำดับการสืบทอดส่งผลต่อความหมายของคลาส ในความกำกวมข้างต้น คลาสBและบรรพบุรุษของมันจะถูกตรวจสอบก่อนคลาสCและบรรพบุรุษของมัน ดังนั้นวิธีการในAจะถูกสืบทอดผ่านBนี่เป็นสิ่งที่ใช้ร่วมกับIoและPicolispใน Perl พฤติกรรมนี้สามารถแทนที่ได้โดยใช้โมดูลmroหรือโมดูลอื่นๆ เพื่อใช้การเรียงลำดับแบบ C3หรืออัลกอริทึมอื่นๆ[ 9 ]
  • Pythonมีโครงสร้างเหมือนกับ Perl แต่ต่างจาก Perl ตรงที่มันรวมอยู่ในไวยากรณ์ของภาษา ลำดับการสืบทอดมีผลต่อความหมายของคลาส Python ต้องจัดการกับเรื่องนี้เมื่อมีการนำคลาสรูปแบบใหม่มาใช้ ซึ่งทั้งหมดมีบรรพบุรุษร่วมกันobjectPython สร้างรายการของคลาสโดยใช้ อัลกอริทึม การเรียงลำดับเชิงเส้น C3 (หรือ Method Resolution Order (MRO)) อัลกอริทึมนี้บังคับใช้ข้อจำกัดสองประการ: ลูกมาก่อนพ่อแม่ และหากคลาสสืบทอดมาจากหลายคลาส คลาสเหล่านั้นจะถูกเก็บไว้ในลำดับที่ระบุไว้ในทูเปิลของคลาสพื้นฐาน (อย่างไรก็ตาม ในกรณีนี้ บางคลาสที่อยู่สูงในกราฟการสืบทอดอาจมาก่อนคลาสที่อยู่ต่ำกว่าในกราฟ[ 10 ] ) ดังนั้น ลำดับการแก้ไขเมธอดคือ: D, B, C, A. [ 11 ]
  • คลาส ใน Rubyมีคลาสแม่เพียงหนึ่งเดียว แต่ก็อาจสืบทอดมาจากหลายโมดูลได้เช่นกัน นิยามของคลาสใน Ruby จะถูกเรียกใช้งาน และการ (กำหนด) นิยามใหม่ของเมธอดจะบดบังนิยามใดๆ ที่มีอยู่ก่อนหน้านี้ในขณะที่เรียกใช้งาน หากไม่มีการเขียนโปรแกรมเมตาในขณะรันไทม์ สิ่งนี้จะมีลักษณะการทำงานคล้ายกับการค้นหาแบบค้นหาจากขวาสุด (rightmost depth first resolution)
  • Scalaอนุญาตให้สร้างอินสแตนซ์ของtrait ได้หลายตัว ซึ่งช่วยให้เกิดการสืบทอดแบบหลายทางโดยการเพิ่มความแตกต่างระหว่างลำดับชั้นของคลาสและลำดับชั้นของ trait คลาสหนึ่งสามารถสืบทอดได้จากคลาสเดียวเท่านั้น แต่สามารถผสมผสาน trait ได้มากเท่าที่ต้องการ Scala จะแก้ไขชื่อเมธอดโดยใช้การค้นหาแบบ depth-first จากขวาไปซ้ายของ 'trait' ที่ขยายออกไป ก่อนที่จะกำจัดโมดูลทั้งหมด ยกเว้นโมดูลที่ปรากฏครั้งสุดท้ายในรายการผลลัพธ์ ดังนั้นลำดับการแก้ไขคือ: [ D, C, A, B, A] ซึ่งจะลดลงเหลือ [ D, C, B, A]
  • Tclอนุญาตให้มีคลาสแม่หลายคลาส ลำดับการระบุในการประกาศคลาสมีผลต่อการแก้ไขชื่อสำหรับสมาชิกโดยใช้อัลกอริทึมการทำให้เป็นเส้นตรง C3 [ 12 ]

ภาษาที่อนุญาตให้มีการสืบทอดแบบเดี่ยว เท่านั้น ซึ่งคลาสสามารถสืบทอดมาจากคลาสพื้นฐานได้เพียงคลาสเดียว จะไม่มีปัญหาเพชร เหตุผลก็คือ ภาษาดังกล่าวจะมีวิธีการใช้งานเพียงวิธีเดียวในแต่ละระดับของห่วงโซ่การสืบทอด โดยไม่คำนึงถึงการทำซ้ำหรือตำแหน่งของวิธีการใช้งาน โดยทั่วไป ภาษาเหล่านี้อนุญาตให้คลาสใช้งานโปรโตคอลได้หลายโปรโตคอลซึ่งเรียกว่าอินเทอร์เฟซใน Java โปรโตคอลเหล่านี้กำหนดวิธีการใช้งาน แต่ไม่ได้ให้วิธีการใช้งานที่เป็นรูปธรรม กลยุทธ์นี้ถูกใช้โดยActionScript , C# , D , Java , Nemerle , Object Pascal , Objective-C , Smalltalk , SwiftและPHP [ 13 ] ภาษาเหล่า นี้ทั้งหมดอนุญาตให้คลาสใช้งานโปรโตคอลได้หลายโปรโตคอล

นอกจากนี้ภาษา Ada , C#, Java, Object Pascal, Objective-C, Swift และ PHP อนุญาตให้มีการสืบทอดแบบหลายทางของอินเทอร์เฟซ (เรียกว่าโปรโตคอลใน Objective-C และ Swift) อินเทอร์เฟซเปรียบเสมือนคลาสพื้นฐานนามธรรมที่ระบุลายเซ็นของเมธอดโดยไม่ใช้งานพฤติกรรมใดๆ (“อินเทอร์เฟซบริสุทธิ์” เช่นใน Java จนถึงเวอร์ชัน 7 ไม่อนุญาตให้มีการใช้งานหรือข้อมูลอินสแตนซ์ใดๆ ในอินเทอร์เฟซ) อย่างไรก็ตาม แม้ว่าจะมีอินเทอร์เฟซหลายตัวที่ประกาศลายเซ็นของเมธอดเดียวกัน แต่ทันทีที่เมธอดนั้นถูกใช้งาน (กำหนด) ที่ใดก็ตามในสายการสืบทอด มันจะแทนที่การใช้งานใดๆ ของเมธอดนั้นในสายการสืบทอดที่สูงกว่า (ในคลาสแม่) ดังนั้น ในระดับใดๆ ในสายการสืบทอด จะมีการใช้งานของเมธอดใดๆ ได้มากที่สุดเพียงหนึ่งเดียวเท่านั้น ดังนั้น การใช้งานเมธอดแบบสืบทอดทางเดียวจึงไม่แสดงปัญหาไดมอนด์แม้จะมีการสืบทอดแบบหลายทางของอินเทอร์เฟซก็ตาม ด้วยการแนะนำการใช้งานเริ่มต้นสำหรับอินเทอร์เฟซใน Java 8 และ C# 8 ยังคงเป็นไปได้ที่จะสร้างปัญหาไดมอนด์ แม้ว่าจะปรากฏเป็นข้อผิดพลาดในระหว่างการคอมไพล์เท่านั้น

ดูเพิ่มเติม

อ่านเพิ่มเติม

  • Stroustrup, Bjarne (1999). การสืบทอดแบบหลายทางสำหรับ C++รายงานการประชุมกลุ่มผู้ใช้ Unix แห่งยุโรป ฤดูใบไม้ผลิ ปี 1987
  • การสร้างซอฟต์แวร์เชิงวัตถุ ฉบับพิมพ์ครั้งที่สอง โดยเบอร์ทรานด์ เมเยอร์สำนักพิมพ์เพรนติส ฮอลล์ ปี 1997 ISBN 0-13-629155-4
  • Eddy Truyen; Wouter Joosen; Bo Nørregaard; Pierre Verbaeten (2004). "การสรุปและวิธีแก้ปัญหาภาวะกลืนไม่เข้าคายไม่ออกของบรรพบุรุษร่วมกันในระบบวัตถุแบบใช้การมอบหมาย" (PDF)รายงานการประชุมเชิงปฏิบัติการ Dynamic Aspects ปี 2004 ( 103–119 )
  • Ira R. Forman; Scott Danforth (1999). การนำเมตาคลาสไปใช้งาน . ISBN 0-201-43305-2.
  • บทแนะนำการใช้งานการสืบทอดใน Eiffel
  • บทช่วยสอนเกี่ยวกับการใช้งานการสืบทอดแบบหลายทางอย่างมีประสิทธิภาพในภาษา Python
  • ภาพรวมของการสืบทอดคุณสมบัติใน OCaml
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Multiple_inheritance&oldid=1344634788#The_diamond_problem "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ การสืบทอดทางพันธุกรรมหลายทาง

การสืบทอดแบบหลายทาง (Multiple inheritance) เป็นคุณลักษณะของ ภาษาการเขียน โปรแกรมเชิง วัตถุ บางภาษา ซึ่งวัตถุหรือ คลาส สามารถ สืบทอด คุณลักษณะจากวัตถุหรือ คลาส...

รายละเอียด

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

การนำไปใช้

ภาษาที่รองรับการสืบทอดแบบหลายทาง ได้แก่ C++ , Common Lisp (ผ่าน Common Lisp Object System (CLOS)), EuLisp (ผ่าน The EuLisp Object System TELOS), Curl , Dylan , Eiffel , Logtalk , Object REXX , Scala (ผ่านการใช้ คลาส mixin ), OCaml , Perl , POP-11 , Python , R...

ปัญหาเพชร

“ ปัญหาเพชร ” (บางครั้งเรียกว่า “เพชรมรณะ” [ 6 ] ) เป็นความกำกวมที่เกิดขึ้นเมื่อคลาส B และ C สองคลาสสืบทอดมาจาก A และคลาส D สืบทอดมาจากทั้ง B และ C หากมีเมธอดใน A ที่ B และ C เขียน ทับ และ D ไม่ได้เขียนทับเมธอดนั้น D จะสืบทอดเมธอดเวอร์ชันใด: เวอร์ชันของ B...