มีภาษา OO ที่ไม่มีมรดกหรือไม่


22

ในระหว่างการตรวจสอบรหัสในวันนี้เพื่อนร่วมงานของฉันพูดสิ่งที่น่าสนใจ:

prototypeมีประโยชน์เฉพาะเมื่อคุณต้องการรับมรดก - และเมื่อใดที่การรับมรดกเป็นความคิดที่ดี ?

ฉันคิดเกี่ยวกับเรื่องนี้และฉันรู้ว่าฉันมักจะใช้การสืบทอดเพื่อรับรหัสที่ออกแบบมาไม่ดีตั้งแต่แรก สไตล์โมเดิร์น OO ชอบองค์ประกอบมรดก แต่ผมไม่ทราบว่าภาษาใด ๆ ที่มีการดำเนินการนี้เพื่อหัวใจและจริงบังคับมัน

มีภาษาการเขียนโปรแกรมวัตถุประสงค์ทั่วไปที่มีคลาสวัตถุวิธีการอินเทอร์เฟซและอื่น ๆ ซึ่งไม่อนุญาตให้สืบทอดตามคลาสหรือไม่ (หากความคิดดังกล่าวไม่สมเหตุสมผลทำไมไม่ทำ)


7
เพื่อนร่วมงานของคุณทำให้คุณหลงทาง สิ่งprototypeนี้ยังมีประโยชน์เมื่อคุณมีวิธีสาธารณะและคุณสมบัติที่ควรใช้ร่วมกันระหว่างอินสแตนซ์ นอกจากนี้ยังเป็นประโยชน์เพราะจะช่วยให้คุณที่จะต้องใช้instanceofประกอบการใน if (foo instanceof Foo) { ...JavaScript:
Greg Burghardt

2
ฉันคิดว่าเราควรแยกความแตกต่างระหว่างการสืบทอดประเภทรัฐและพฤติกรรม การกำหนดลักษณะของการเรียบเรียงเป็นเรื่องธรรมดามากในชุมชน Java แต่ในเวลาเดียวกันการสืบทอด (และแม้กระทั่งการสืบทอดหลายครั้ง) ของชนิดถูกใช้และสนับสนุนอย่างกว้างขวาง ... และตระหนักถึงการใช้implementsคำสำคัญและอินเทอร์เฟซ พฤติกรรมที่นำมาใช้กับการใช้extendsคำหลักในชั้นเรียนที่มีการใช้งานใด ๆ )
toniedzwiedz

6
การชอบแต่งเพลงไม่ได้หมายความว่าการละทิ้งมรดกอย่างสมบูรณ์เป็นความคิดที่ดี
แม็กเคเล็บ

5
ดูJava โดยไม่ต้องสืบทอดการใช้งาน : "Go's ของ Google เป็นตัวอย่างของภาษาที่ไม่เกี่ยวข้องกับการสืบทอดการใช้งานในขณะที่เป็น OOP ... "
gnat

1
@GregBurghardt สามารถทำเช่นเดียวกันกับฟังก์ชั่นจากโรงงานซึ่งส่งคืนวัตถุที่มีฟังก์ชั่น (จัดเก็บข้อมูลส่วนตัวในการปิด) new, thisและprototypeทุกคนมากเกินไปของทุ่นระเบิดสำหรับการใช้งานร่วมกัน IMO
Benjamin Hodgson

คำตอบ:


18

การตั้งคำถามของคำนิยามของการเขียนโปรแกรมเชิงวัตถุคำถามกลายเป็นหนึ่งใน "มีภาษาที่ใช้การแต่งเพลงเท่านั้นและไม่มีเครื่องมือสำหรับการสืบทอด?"

คำตอบสำหรับคำถามนี้คือ "ใช่" ในระหว่างการเดินทางไม่มีทางที่จะทำมรดกได้ตามที่คนคิดแบบคลาสสิก หนึ่งสามารถฝังวัตถุในวัตถุอื่นและขยายวัตถุนั้น จากObject Desoriented Language ( gitub mirror ):

type Person struct {
        Name string
}

func (p *Person) Intro() string {
        return p.Name
}

type Woman struct {
        Person
}

func (w *Woman) Intro() string {
        return "Mrs. " + w.Person.Intro()
}

คุณมีโครงสร้างบุคคลที่มีชื่อซึ่งเป็นสตริง มันมีฟังก์ชั่นสาธารณะที่เรียกว่า Intro ซึ่งจะส่งกลับชื่อ Struct ผู้หญิงยังมีฟังก์ชั่นสำหรับ Intro ซึ่งเข้าถึง strut ที่ฝังอยู่ในนั้น และอย่างใดอย่างหนึ่งสามารถบรรลุเจตนาของการสืบทอดโดยใช้การเรียงความเท่านั้น

เพิ่มเติมเกี่ยวกับเรื่องนี้สามารถมองเห็นที่golang Tutorials: มรดกและ subclassing ในไป - หรืออุปมาที่อยู่ใกล้

ใช่มันเป็นไปได้ที่จะมีภาษา OO โดยไม่มีการสืบทอดและมีอยู่จริง

ภายในไปนี้เรียกว่าการฝังและให้โครงสร้างล้อมรอบความสามารถในการเข้าถึงเขตข้อมูลที่ฝังตัวและฟังก์ชั่นราวกับว่ามันมีพวกเขาด้วย - แต่มันไม่ได้เป็นคลาสย่อย ปรัชญาการออกแบบสามารถพบได้ในคำถามที่พบบ่อย Go: ทำไมจึงไม่มีการถ่ายทอดทางพันธุกรรม?


หนึ่งยังสามารถแสดงความคิดเห็นเกี่ยวกับการใช้typedefและstructใน C ...
cwallenpoole

@ carenpoole มีความคิดที่คล้ายกันจริง ๆ แม้ว่าฉันจะลังเลที่จะโทรหา C ซึ่งเป็นภาษาเชิงวัตถุ

ฉันไม่รู้. ฉันจะยอมรับความจริงที่ว่าคุณไม่สามารถสร้างวัตถุที่มีฟังก์ชั่นที่แนบมาทำงานได้กับมัน แต่ถ้าไม่มีการสืบทอด OOP จะสูญเสียรสชาติไปมาก
cwallenpoole

@callenpoole และเราเริ่มที่จะกำหนดสิ่งที่เป็นมรดกและการวางแนววัตถุ แต่มันเป็นไปได้มันเป็นวิธีคิดที่แตกต่างเกี่ยวกับปัญหา ประเด็นก็คือการสืบทอดเป็นวิธีที่โปรแกรมเมอร์ C ++ และ Java ส่วนใหญ่คิดว่าเป็นส่วนขยาย ... แต่มีรุ่นอื่น ๆ อยู่ ส่วนขยายที่ไม่มีการสืบทอด: 1 , 2 , 3เป็นการอ่านที่ดี

เชื่อมโยงไปยัง "วัตถุ Desoriented ภาษา" จะติดอยู่ในวงเปลี่ยนเส้นทางในขณะนี้ แต่ผมพบว่าบทความที่นี่: github.com/nu7hatch/areyoufuckingcoding.me/blob/master/content/... ขอบคุณ!
Matt Browne

7

มีภาษาการเขียนโปรแกรมวัตถุประสงค์ทั่วไปที่มีคลาสวัตถุวิธีการอินเทอร์เฟซและอื่น ๆ ซึ่งไม่อนุญาตให้สืบทอดตามคลาสหรือไม่

สิ่งนี้อ่านคล้ายกับคำอธิบายของ VBA - Visual Basic สำหรับแอปพลิเคชันที่ฝังอยู่ใน Microsoft Office และโฮสต์ที่เปิดใช้งาน VBA อื่น ๆ (เช่น AutoCAD, Sage 300 ERP ฯลฯ ) หรือแม้แต่ VB6 "A" ของ "พื้นฐาน" หมายถึง "อเนกประสงค์" ดังนั้นจึงมีส่วน "วัตถุประสงค์ทั่วไป"

VB6 / VBA มีคลาส (และวัตถุ) วิธีการและอินเทอร์เฟซ - คุณสามารถกำหนดISomethingอินเทอร์เฟซในโมดูลคลาสเช่นนี้:

Option Explicit

Public Sub DoSomething()
End Sub

แล้วมีคลาสอื่นที่ทำสิ่งนี้:

Option Explicit
Implements ISomething

Private Sub ISomething_DoSomething()
    'implementation here
End Sub

คลาสดังกล่าวซึ่งไม่มีสมาชิกสาธารณะสามารถเข้าถึงได้ผ่านทางISomethingอินเทอร์เฟซเท่านั้นและอาจมีการใช้งานที่แตกต่างกันISomethingออกไปมากมายดังนั้นรหัส OOP VBA จึงมีความสามารถหลากหลายและสมบูรณ์แบบสำหรับชั้นเรียนที่กำหนด เพื่อใช้หลายอินเตอร์เฟสเช่นกัน

VB6 / VBA ไม่อนุญาตให้สืบทอดคลาสอย่างไรก็ตามคุณไม่สามารถสืบทอดการใช้งานจากประเภทอื่นได้เพียงอินเตอร์เฟส ตอนนี้ไม่ว่าจะเป็นอุบัติเหตุข้อบกพร่องในการออกแบบจังหวะอัจฉริยะหรือการกำกับดูแลที่น่าเกลียดขนาดใหญ่เปิดให้อภิปราย มันไม่ชัดเจนว่า VB6 / VBA จะใช้เวลานี้ไปยังหัวใจแต่มันแน่นอนที่สุดบังคับมัน

ถ้าGo ไม่ทำการสืบทอดคลาสและเป็นภาษา OOP อย่างไรก็ตามฉันไม่เห็นว่าทำไม VB6 / VBA จึงไม่สามารถใช้ภาษา OOP ได้เช่นกัน</PreemptiveResponseToVBAHatersThatWillSayItIsNotAnOOPLanguage>


1
เพื่อความเป็นธรรม OP ถามเกี่ยวกับภาษาสมัยใหม่ =;) -
RubberDuck

@RubberDuck #burn!
Mathieu Guindon

0

คุณสามารถทำให้คอมไพเลอร์บังคับใช้การสืบทอดแบบเลือกผ่านการใช้งานส่วนตัว / ได้รับการป้องกันและผ่านการใช้เทคนิค "PImpl" หรือ "การใช้งานส่วนตัว" ที่ทันสมัย

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

การค้นหาอย่างรวดเร็วสำหรับฟังก์ชั่นสมาชิกส่วนตัวในจาวาสคริปต์แสดงว่ามีหลักการที่คล้ายกันแม้ว่าใคร ๆ ก็สามารถดูรหัสของคุณได้หากพวกเขาสามารถใช้งานได้: http://www.crockford.com/javascript/private.html

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