ฉันรู้ว่าไม่อนุญาตให้มีการสืบทอดหลายรายการใน Java และ C # หนังสือหลายเล่มบอกว่าไม่อนุญาตให้มีการสืบทอดหลาย ๆ แต่สามารถใช้งานได้โดยใช้อินเทอร์เฟซ ไม่มีการพูดคุยเกี่ยวกับสาเหตุที่ไม่อนุญาต ใครช่วยบอกทีว่าทำไมถึงไม่อนุญาต?
ฉันรู้ว่าไม่อนุญาตให้มีการสืบทอดหลายรายการใน Java และ C # หนังสือหลายเล่มบอกว่าไม่อนุญาตให้มีการสืบทอดหลาย ๆ แต่สามารถใช้งานได้โดยใช้อินเทอร์เฟซ ไม่มีการพูดคุยเกี่ยวกับสาเหตุที่ไม่อนุญาต ใครช่วยบอกทีว่าทำไมถึงไม่อนุญาต?
คำตอบ:
คำตอบสั้น ๆ คือเพราะนักออกแบบภาษาตัดสินใจที่จะไม่ทำ
โดยทั่วไปก็ดูเหมือนว่าทั้ง NET และนักออกแบบ Java ไม่อนุญาตให้มรดกหลายเพราะพวกเขาให้เหตุผลว่าการเพิ่ม MI เพิ่มความซับซ้อนมากเกินไปกับภาษาในขณะที่ให้ประโยชน์น้อยเกินไป
เพื่อความสนุกสนานและการอ่านเชิงลึกยิ่งขึ้นมีบทความบางส่วนในเว็บพร้อมบทสัมภาษณ์ของนักออกแบบภาษาบางคน ตัวอย่างเช่นสำหรับ. NET Chris Brumme (ซึ่งทำงานที่ MS บน CLR) ได้อธิบายถึงสาเหตุที่พวกเขาตัดสินใจที่จะไม่:
ภาษาที่แตกต่างกันมีความคาดหวังที่แตกต่างกันสำหรับวิธีการทำงานของ MI ตัวอย่างเช่นวิธีแก้ไขความขัดแย้งและการรวมฐานที่ซ้ำกันหรือซ้ำซ้อน ก่อนที่เราจะนำ MI ไปใช้ใน CLR เราต้องทำการสำรวจภาษาทั้งหมดหาแนวคิดทั่วไปและตัดสินใจว่าจะแสดงออกอย่างไรในลักษณะที่เป็นกลางทางภาษา เราจะต้องตัดสินใจด้วยว่า MI อยู่ใน CLS หรือไม่และหมายความว่าอย่างไรสำหรับภาษาที่ไม่ต้องการแนวคิดนี้ (น่าจะเป็น VB.NET เป็นต้น) แน่นอนว่านั่นเป็นธุรกิจที่เราใช้ในฐานะรันไทม์ภาษาทั่วไป แต่เรายังไม่ได้ทำเพื่อ MI
จำนวนสถานที่ที่ MI เหมาะสมอย่างแท้จริงนั้นค่อนข้างน้อย ในหลาย ๆ กรณีการสืบทอดอินเทอร์เฟซหลายตัวสามารถทำให้งานสำเร็จแทนได้ ในกรณีอื่นคุณอาจใช้การห่อหุ้มและการมอบหมายได้ ถ้าเราเพิ่มโครงสร้างที่แตกต่างกันเล็กน้อยเช่นมิกซ์อินมันจะมีพลังมากกว่านี้จริงหรือ?
การสืบทอดการนำไปใช้งานหลาย ๆ อย่างทำให้เกิดความซับซ้อนมากมายในการนำไปใช้งาน ความซับซ้อนนี้ส่งผลกระทบต่อการแคสต์การจัดวางการจัดส่งการเข้าถึงภาคสนามการทำให้เป็นอนุกรมการเปรียบเทียบข้อมูลประจำตัวการตรวจสอบความถูกต้องการสะท้อนข้อมูลทั่วไปและที่อื่น ๆ อีกมากมาย
คุณสามารถอ่านบทความฉบับเต็มได้ที่นี่
สำหรับ Java คุณสามารถอ่านบทความนี้ :
สาเหตุของการละเว้นการสืบทอดหลายรายการจากภาษา Java ส่วนใหญ่เกิดจากเป้าหมาย "เรียบง่ายเชิงวัตถุและคุ้นเคย" ในฐานะภาษาที่เรียบง่ายผู้สร้างของ Java ต้องการภาษาที่นักพัฒนาส่วนใหญ่สามารถเข้าใจได้โดยไม่ต้องมีการฝึกอบรมมากมาย ด้วยเหตุนี้พวกเขาจึงพยายามทำให้ภาษาใกล้เคียงกับ C ++ มากที่สุด (คุ้นเคย) โดยไม่ต้องใช้ความซับซ้อนที่ไม่จำเป็นของ C ++ (ง่าย ๆ )
ในความคิดของนักออกแบบการสืบทอดหลายอย่างทำให้เกิดปัญหาและความสับสนมากกว่าที่จะแก้ได้ ดังนั้นพวกเขาจึงตัดการสืบทอดหลาย ๆ ภาษาออกไป (เช่นเดียวกับที่พวกเขาตัดตัวดำเนินการมากเกินไป) ประสบการณ์ C ++ ที่กว้างขวางของนักออกแบบสอนให้พวกเขารู้ว่าการสืบทอดหลาย ๆ อย่างไม่คุ้มค่ากับการปวดหัว
การสืบทอดการใช้งานหลายครั้งเป็นสิ่งที่ไม่ได้รับอนุญาต
ปัญหาคือคอมไพเลอร์ / รันไทม์ไม่สามารถคิดได้ว่าจะทำอย่างไรถ้าคุณมีคลาส Cowboy และ Artist ทั้งที่มีการใช้งานสำหรับเมธอด draw () จากนั้นคุณพยายามสร้างประเภท CowboyArtist ใหม่ จะเกิดอะไรขึ้นเมื่อคุณเรียกใช้เมธอด draw () มีคนนอนตายอยู่บนถนนหรือคุณมีสีน้ำน่ารัก ๆ ?
ฉันเชื่อว่ามันเรียกว่าปัญหามรดกเพชรคู่
เหตุผล: Java เป็นที่นิยมมากและง่ายต่อการเขียนโค้ดเนื่องจากความเรียบง่าย
ดังนั้นสิ่งที่นักพัฒนา java รู้สึกยากและซับซ้อนในการทำความเข้าใจสำหรับโปรแกรมเมอร์พวกเขาพยายามหลีกเลี่ยง ทรัพย์สินประเภทหนึ่งคือมรดกหลายรายการ
ปัญหาเกี่ยวกับการสืบทอดหลายรายการ:ปัญหาเพชร
ตัวอย่าง :
นี่คือความไม่ชัดเจนที่มีอยู่ในปัญหาเพชร
ไม่ใช่เรื่องที่เป็นไปไม่ได้ที่จะแก้ปัญหานี้ แต่จะสร้างความสับสนและความซับซ้อนให้กับโปรแกรมเมอร์มากขึ้นในขณะที่อ่าน มันทำให้เกิดปัญหามากกว่าที่จะพยายามแก้ไข
หมายเหตุ : แต่วิธีใดก็ตามที่คุณสามารถใช้การสืบทอดทางอ้อมโดยใช้อินเทอร์เฟซ
เนื่องจาก Java มีปรัชญาการออกแบบที่แตกต่างจาก C ++ อย่างมาก (ฉันจะไม่พูดถึง C # ที่นี่)
ในการออกแบบ C ++ Stroustrup ต้องการรวมคุณสมบัติที่มีประโยชน์โดยไม่คำนึงถึงวิธีการใช้งานในทางที่ผิด เป็นไปได้ที่จะจัดการครั้งใหญ่ด้วยการสืบทอดหลายรายการการโอเวอร์โหลดตัวดำเนินการเทมเพลตและคุณสมบัติอื่น ๆ อีกมากมาย แต่ก็เป็นไปได้ที่จะทำสิ่งที่ดีกับพวกเขา
ปรัชญาการออกแบบ Java คือการเน้นความปลอดภัยในโครงสร้างภาษา ผลลัพธ์ก็คือมีหลายสิ่งที่น่าอึดอัดใจที่ต้องทำ แต่คุณสามารถมั่นใจได้มากขึ้นว่าโค้ดที่คุณกำลังดูหมายถึงสิ่งที่คุณคิดว่ามันทำ
นอกจากนี้ Java ยังเป็นปฏิกิริยาจาก C ++ และ Smalltalk ซึ่งเป็นภาษา OO ที่รู้จักกันดีที่สุด มีภาษา OO อื่น ๆ มากมาย (Common Lisp เป็นภาษาแรกที่เป็นมาตรฐาน) โดยมีระบบ OO ต่างๆที่จัดการ MI ได้ดีกว่า
ไม่ต้องพูดถึงว่าเป็นไปได้ทั้งหมดที่จะทำ MI ใน Java โดยใช้อินเทอร์เฟซองค์ประกอบและการมอบหมาย มีความชัดเจนมากกว่าใน C ++ ดังนั้นจึงใช้งานได้ง่ายกว่า แต่จะทำให้คุณได้รับสิ่งที่คุณน่าจะเข้าใจได้มากกว่าในครั้งแรก
ไม่มีคำตอบที่ถูกต้องที่นี่ มีคำตอบที่แตกต่างกันและคำตอบใดดีกว่าสำหรับสถานการณ์ที่กำหนดขึ้นอยู่กับการใช้งานและความชอบของแต่ละบุคคล
เหตุผลหลัก (แม้ว่าจะไม่ใช่เหตุผลเดียว) ที่ผู้คนหลีกเลี่ยง MI คือสิ่งที่เรียกว่า "ปัญหาเพชร" ที่นำไปสู่ความคลุมเครือในการนำไปปฏิบัติของคุณ นี้บทความวิกิพีเดียกล่าวถึงมันและอธิบายดีกว่าที่ผมจะทำได้ MI ยังสามารถนำไปสู่โค้ดที่ซับซ้อนมากขึ้นและนักออกแบบ OO จำนวนมากอ้างว่าคุณไม่จำเป็นต้องใช้ MI และหากคุณใช้แบบจำลองของคุณอาจผิด ฉันไม่แน่ใจว่าฉันเห็นด้วยกับประเด็นสุดท้ายนี้ แต่การรักษาสิ่งต่างๆให้เรียบง่ายอยู่เสมอเป็นแผนการที่ดี
ในการสืบทอดหลาย ๆ C ++ เป็นอาการปวดหัวอย่างมากเมื่อใช้ไม่ถูกต้อง เพื่อหลีกเลี่ยงปัญหาการออกแบบที่เป็นที่นิยมเหล่านั้นอินเทอร์เฟซหลาย ๆ "การสืบทอด" ถูกบังคับให้ใช้ภาษาสมัยใหม่แทน (java, C #)
การสืบทอดหลายรายการคือ
ดังนั้นจึงถือได้ว่าเป็นทางเลือกที่ชาญฉลาดที่จะไม่รวมการสืบทอดหลายรายการลงในภาษา Java
อีกเหตุผลหนึ่งคือการสืบทอดครั้งเดียวทำให้การหล่อเป็นเรื่องเล็กน้อยโดยไม่มีคำแนะนำในการประกอบ (นอกเหนือจากการตรวจสอบความเข้ากันได้ของประเภทที่จำเป็น) หากคุณมีการสืบทอดหลายรายการคุณต้องหาว่าผู้ปกครองเริ่มต้นที่ใดในคลาสย่อย ดังนั้นประสิทธิภาพจึงเป็นประโยชน์อย่างแน่นอน (แม้ว่าจะไม่ใช่เพียงอย่างเดียว)
ย้อนกลับไปในสมัยก่อน (ยุค 70) เมื่อวิทยาการคอมพิวเตอร์เป็นวิทยาศาสตร์มากขึ้นและการผลิตจำนวนมากน้อยลงโปรแกรมเมอร์มีเวลาคิดเกี่ยวกับการออกแบบที่ดีและการนำไปใช้งานที่ดีและเป็นผลให้ผลิตภัณฑ์ (โปรแกรม) มีคุณภาพสูง (เช่นการออกแบบ TCP / IP และการนำไปใช้งาน) ทุกวันนี้เมื่อทุกคนกำลังเขียนโปรแกรมและผู้จัดการกำลังเปลี่ยนข้อกำหนดก่อนกำหนดเวลาปัญหาที่ละเอียดอ่อนเช่นที่อธิบายไว้ในลิงก์วิกิพีเดียจากโพสต์ของ Steve Haigh นั้นยากที่จะติดตาม ดังนั้น "การสืบทอดหลายรายการ" จึงถูก จำกัด โดยการออกแบบคอมไพเลอร์ หากคุณชอบคุณยังสามารถใช้ C ++ ได้ .... และมีอิสระทุกอย่างที่คุณต้องการ :)
ฉันใช้คำพูดที่ว่า "ไม่อนุญาตให้มีการสืบทอดหลายรายการใน Java" ด้วยเกลือเล็กน้อย
การสืบทอดหลายรายการถูกกำหนดเมื่อ "ประเภท" สืบทอดมาจาก "ประเภท" มากกว่าหนึ่งรายการ และอินเทอร์เฟซยังจัดเป็นประเภทตามที่มีพฤติกรรม ดังนั้น Java จึงมีการสืบทอดหลายรายการ แค่นั้นก็ปลอดภัยกว่า
การโหลดคลาสแบบไดนามิกทำให้การใช้งานการสืบทอดหลายรายการทำได้ยาก
ใน java จริง ๆ แล้วพวกเขาหลีกเลี่ยงความซับซ้อนของการสืบทอดหลายรายการแทนโดยใช้การสืบทอดและอินเทอร์เฟซเดียว ความซับซ้อนของการถ่ายทอดทางพันธุกรรมสูงมากในสถานการณ์ที่อธิบายไว้ด้านล่าง
ปัญหาเพชรของการสืบทอดหลายรายการ เรามีคลาส B และ C สองคลาสที่สืบทอดมาจาก A สมมติว่า B และ C กำลังลบล้างวิธีการที่สืบทอดมาและจัดเตรียมการนำไปใช้งานของตนเอง ตอนนี้ D รับช่วงจากทั้ง B และ C โดยทำการสืบทอดหลายรายการ D ควรสืบทอดวิธีการที่ถูกลบล้างนั้น jvm ไม่สามารถตัดสินใจได้ว่าจะใช้วิธีการลบล้างใด?
ในฟังก์ชันเสมือน c ++ ถูกใช้เพื่อจัดการและเราต้องทำอย่างชัดเจน
สิ่งนี้สามารถหลีกเลี่ยงได้โดยใช้อินเทอร์เฟซไม่มีเนื้อหาของวิธีการ อินเทอร์เฟซไม่สามารถสร้างอินสแตนซ์ได้ - สามารถใช้งานได้โดยคลาสหรือขยายโดยอินเทอร์เฟซอื่นเท่านั้น
การสืบทอดหลายรายการจะเกิดความซับซ้อนหากคลาสที่สืบทอดมามีฟังก์ชันเดียวกัน กล่าวคือคอมไพเลอร์จะมีความสับสนที่ต้องเลือก (ปัญหาเพชร) ดังนั้นใน Java ที่ความซับซ้อนถูกลบออกและให้อินเทอร์เฟซเพื่อรับฟังก์ชันเช่นเดียวกับการสืบทอดหลายรายการ เราสามารถใช้อินเตอร์เฟซ
Java มีแนวคิดคือความหลากหลาย ความแตกต่างใน java มี 2 ประเภท มีวิธีการโอเวอร์โหลดและการแทนที่เมธอด ในหมู่พวกเขาการลบล้างวิธีการเกิดขึ้นกับความสัมพันธ์ระดับซุปเปอร์และคลาสย่อย หากเรากำลังสร้างออบเจ็กต์ของคลาสย่อยและเรียกใช้เมธอดของซูเปอร์คลาสและถ้าคลาสย่อยขยายมากกว่าหนึ่งคลาสควรเรียกใช้เมธอดระดับซูเปอร์คลาสใด
หรือในขณะที่เรียก superclass constructor โดยsuper()
super class constructor ตัวไหนจะถูกเรียก?
การตัดสินใจนี้เป็นไปไม่ได้ด้วยคุณสมบัติ java API ปัจจุบัน ดังนั้นจึงไม่อนุญาตให้มีการสืบทอดหลายรายการใน java
ไม่อนุญาตให้มีการสืบทอดหลายรายการใน Java โดยตรง แต่อนุญาตผ่านอินเทอร์เฟซได้
เหตุผล :
การสืบทอดหลายรายการ:ทำให้เกิดความซับซ้อนและความคลุมเครือมากขึ้น
อินเทอร์เฟซ:อินเทอร์เฟซเป็นคลาสนามธรรมอย่างสมบูรณ์ใน Java ที่ให้วิธีการที่สม่ำเสมอในการกำหนดโครงสร้างหรือการทำงานภายในของโปรแกรมของคุณอย่างถูกต้องจากอินเทอร์เฟซที่เปิดเผยต่อสาธารณะด้วยผลที่ตามมาคือความยืดหยุ่นและโค้ดที่ใช้ซ้ำได้มากขึ้นรวมถึงการควบคุมที่มากขึ้น เกี่ยวกับวิธีที่คุณสร้างและโต้ตอบกับชั้นเรียนอื่น ๆ
อย่างแม่นยำยิ่งขึ้นพวกเขาเป็นโครงสร้างพิเศษใน Java ที่มีคุณสมบัติเพิ่มเติมที่ช่วยให้คุณสามารถดำเนินการสืบทอดหลายประเภทเช่นคลาสที่สามารถอัปเดตได้มากกว่าหนึ่งคลาส
มายกตัวอย่างง่ายๆ
สมมติว่ามีคลาสซูเปอร์คลาส 2 คลาส A และ B ที่มีชื่อเมธอดเหมือนกัน แต่ฟังก์ชันต่างกัน ผ่านรหัสต่อไปนี้ที่มีคำหลัก (ขยาย) การสืบทอดหลายคำเป็นไปไม่ได้
public class A
{
void display()
{
System.out.println("Hello 'A' ");
}
}
public class B
{
void display()
{
System.out.println("Hello 'B' ");
}
}
public class C extends A, B // which is not possible in java
{
public static void main(String args[])
{
C object = new C();
object.display(); // Here there is confusion,which display() to call, method from A class or B class
}
}
แต่ผ่านทางอินเทอร์เฟซโดยใช้คำหลัก (implements) การสืบทอดหลายคำเป็นไปได้
interface A
{
// display()
}
interface B
{
//display()
}
class C implements A,B
{
//main()
C object = new C();
(A)object.display(); // call A's display
(B)object.display(); //call B's display
}
}
ใครช่วยบอกทีว่าทำไมถึงไม่อนุญาต?
คุณสามารถหาคำตอบได้จากลิงค์เอกสารนี้
เหตุผลหนึ่งที่ภาษาการเขียนโปรแกรม Java ไม่อนุญาตให้คุณขยายมากกว่าหนึ่งคลาสคือการหลีกเลี่ยงปัญหาของการสืบทอดหลายสถานะซึ่งเป็นความสามารถในการสืบทอดฟิลด์จากหลายคลาส
หากอนุญาตให้มีการสืบทอดหลายรายการและเมื่อคุณสร้างอ็อบเจกต์โดยการสร้างอินสแตนซ์คลาสนั้นอ็อบเจ็กต์นั้นจะสืบทอดฟิลด์จากซูเปอร์คลาสทั้งหมดของคลาส มันจะทำให้เกิดสองประเด็น
จะเกิดอะไรขึ้นถ้าเมธอดหรือตัวสร้างจากซูเปอร์คลาสที่แตกต่างกันสร้างอินสแตนซ์ฟิลด์เดียวกัน
วิธีการหรือตัวสร้างใดจะมีความสำคัญกว่า?
แม้ว่าตอนนี้จะอนุญาตให้มีการสืบทอดหลายสถานะได้ แต่คุณยังสามารถใช้
การสืบทอดหลายประเภท : ความสามารถของคลาสในการใช้งานอินเทอร์เฟซมากกว่าหนึ่ง
การสืบทอดการใช้งานจำนวนมาก (ผ่านวิธีการเริ่มต้นในอินเทอร์เฟซ): ความสามารถในการสืบทอดนิยามวิธีการจากหลายคลาส
อ้างถึงคำถาม SE ที่เกี่ยวข้องนี้สำหรับข้อมูลเพิ่มเติม:
ใน C ++ คลาสสามารถสืบทอด (โดยตรงหรือโดยอ้อม) จากมากกว่าหนึ่งคลาสซึ่งเรียกว่าการ สืบทอดหลายรายการมรดกหลาย
อย่างไรก็ตาม C # และ Java จำกัด คลาสไว้ที่การสืบทอดเดียวแต่ละคลาสสืบทอดมาจากคลาสพาเรนต์เดียว
การสืบทอดหลายชั้นเป็นวิธีที่มีประโยชน์ในการสร้างคลาสที่รวมแง่มุมของลำดับชั้นคลาสสองแบบที่แตกต่างกันซึ่งมักเกิดขึ้นเมื่อใช้คลาสเฟรมเวิร์กที่แตกต่างกันภายในแอปพลิเคชันเดียว
หากสองเฟรมเวิร์กกำหนดคลาสพื้นฐานของตนเองสำหรับข้อยกเว้นตัวอย่างเช่นคุณสามารถใช้การสืบทอดหลายคลาสเพื่อสร้างคลาสข้อยกเว้นที่สามารถใช้ได้กับเฟรมเวิร์กใด
ปัญหาเกี่ยวกับการถ่ายทอดทางพันธุกรรมหลายอย่างคืออาจทำให้เกิดความคลุมเครือ ตัวอย่างคลาสสิกคือเมื่อคลาสสืบทอดมาจากคลาสอื่นสองคลาสซึ่งแต่ละคลาสสืบทอดมาจากคลาสเดียวกัน:
class A {
protected:
bool flag;
};
class B : public A {};
class C : public A {};
class D : public B, public C {
public:
void setFlag( bool nflag ){
flag = nflag; // ambiguous
}
};
ในตัวอย่างนี้ข้อมูลสมาชิกถูกกำหนดโดยflag
class A
แต่class D
ลงมาจากclass B
และclass C
ซึ่งทั้งสองเป็นผลมาจากA
ดังนั้นในสาระสำคัญสองฉบับของflag
ที่มีอยู่เพราะทั้งสองกรณีของA
อยู่ในD
's ลำดับชั้น คุณต้องการตั้งค่าใด คอมไพเลอร์จะบ่นว่าการอ้างอิงถึงflag
ในD
เป็นที่คลุมเครือ การแก้ไขอย่างหนึ่งคือการทำให้ข้อมูลอ้างอิงไม่ชัดเจน:
B::flag = nflag;
การแก้ไขอีกประการหนึ่งคือการประกาศ B และ C เป็นvirtual base classes
ซึ่งหมายความว่ามีสำเนา A เพียงชุดเดียวเท่านั้นที่สามารถมีอยู่ในลำดับชั้นเพื่อขจัดความคลุมเครือใด ๆ
ความซับซ้อนอื่น ๆ มีอยู่พร้อมกับการสืบทอดหลายรายการเช่นลำดับที่คลาสพื้นฐานถูกเตรียมใช้งานเมื่อสร้างอ็อบเจ็กต์ที่ได้รับหรือวิธีที่สมาชิกสามารถซ่อนโดยไม่ได้ตั้งใจจากคลาสที่ได้รับ เพื่อหลีกเลี่ยงความซับซ้อนเหล่านี้บางภาษา จำกัด ตัวเองให้อยู่ในรูปแบบการสืบทอดเดียวที่ง่ายกว่า
แม้ว่าสิ่งนี้จะทำให้การถ่ายทอดทางพันธุกรรมง่ายขึ้นมาก แต่ก็ยัง จำกัด ประโยชน์ของมันเนื่องจากมีเพียงคลาสที่มีบรรพบุรุษร่วมกันเท่านั้นที่สามารถแบ่งปันพฤติกรรมได้ อินเทอร์เฟซช่วยลดข้อ จำกัด นี้ได้บ้างโดยอนุญาตให้คลาสที่อยู่ในลำดับชั้นต่างๆแสดงอินเทอร์เฟซทั่วไปแม้ว่าจะไม่ได้ใช้งานโดยใช้โค้ดร่วมกันก็ตาม
ลองนึกภาพตัวอย่างนี้: ฉันมีชั้นเรียน Shape1
มีCalcualteArea
วิธีการ:
Class Shape1
{
public void CalculateArea()
{
//
}
}
มีคลาสอื่นShape2
ที่มีวิธีการเดียวกัน
Class Shape2
{
public void CalculateArea()
{
}
}
ตอนนี้ฉันมี Circle คลาสเด็กมันมาจากทั้ง Shape1 และ Shape2
public class Circle: Shape1, Shape2
{
}
ตอนนี้เมื่อฉันสร้างวัตถุสำหรับ Circle และเรียกใช้เมธอดระบบไม่ทราบว่าจะเรียกใช้วิธีการคำนวณพื้นที่ใด ทั้งสองมีลายเซ็นเดียวกัน ดังนั้นคอมไพเลอร์จะสับสน นั่นเป็นเหตุผลที่ไม่อนุญาตให้มีการสืบทอดหลายรายการ
แต่สามารถมีได้หลายอินเทอร์เฟซเนื่องจากอินเทอร์เฟซไม่มีการกำหนดวิธีการ แม้ว่าอินเทอร์เฟซทั้งสองจะมีวิธีการเดียวกัน แต่ทั้งสองก็ไม่มีการนำไปใช้งานใด ๆ และจะเรียกใช้วิธีการในคลาสลูกเสมอ