แนวคิดเรื่อง“ องค์ประกอบของความโปรดปรานเหนือมรดก” นี้มาจากไหน?


143

ในช่วงไม่กี่เดือนที่ผ่านมามนต์ "องค์ประกอบที่เป็นที่โปรดปรานเหนือมรดก" ดูเหมือนจะเด้งขึ้นมาจากที่ไหนเลยและกลายเป็นเกือบ meme บางอย่างภายในชุมชนการเขียนโปรแกรม และทุกครั้งที่ฉันเห็นฉันก็รู้สึกงงเล็กน้อย มันเหมือนมีคนพูดว่า "ชอบการฝึกฝนมากกว่าค้อน" จากประสบการณ์ของฉันการจัดองค์ประกอบและการรับมรดกเป็นเครื่องมือสองแบบที่แตกต่างกันกับกรณีการใช้งานที่แตกต่างกันและจัดการกับมันราวกับว่าพวกมันใช้แทนกันได้และอีกอันหนึ่งเหนือกว่าอีกอันหนึ่ง

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

ไม่มีใครรู้ว่าแนวคิดนี้มาจากไหนและเหตุผลที่อยู่เบื้องหลังมันคืออะไร?


45
อย่างที่คนอื่น ๆ ชี้ไปมันเป็นเวลานานแล้ว - ฉันประหลาดใจที่คุณเพิ่งได้ยินมัน มันง่ายสำหรับทุกคนที่ได้สร้างระบบใหญ่ในภาษาเช่น Java ตลอดเวลา มันเป็นสิ่งสำคัญสำหรับการสัมภาษณ์ใด ๆ ที่ฉันเคยให้และเมื่อผู้สมัครเริ่มพูดคุยเกี่ยวกับมรดกฉันเริ่มสงสัยระดับทักษะและจำนวนประสบการณ์ของพวกเขา ต่อไปนี้เป็นคำแนะนำที่ดีเกี่ยวกับสาเหตุที่การสืบทอดเป็นวิธีแก้ปัญหาที่เปราะบาง (อื่น ๆ อีกมากมาย): artima.com/lejava/articles/designprinciples4.html
Janx

6
@Janx: อาจเป็นได้ ฉันไม่ได้สร้างระบบขนาดใหญ่ในภาษาเช่น Java; ฉันสร้างมันใน Delphi และหากไม่มีการทดแทน Liskov และ polymorphism เราก็ไม่เคยทำอะไรเลย โมเดลวัตถุของมันแตกต่างกันในบางวิธีมากกว่า Java หรือ C ++ และปัญหามากมายที่ maxim นี้ดูเหมือนว่ามีไว้เพื่อแก้ไขไม่ได้มีอยู่จริงหรือมีปัญหาน้อยกว่ามากใน Delphi ฉันคิดว่ามุมมองที่แตกต่างจากมุมมองที่ต่างกัน
Mason Wheeler

14
ฉันใช้เวลาหลายปีในการสร้างทีมระบบที่ค่อนข้างใหญ่ในเดลฟีและต้นไม้มรดกที่สูงกัดทีมของเราและทำให้เราเจ็บปวดอย่างมาก ฉันสงสัยว่าความสนใจของคุณต่อหลักการ SOLID นั้นช่วยให้คุณหลีกเลี่ยงปัญหาที่เกิดขึ้นไม่ใช่การใช้ Delphi ของคุณ
Bevan

8
ไม่กี่เดือนที่ผ่านมา
Jas

6
IMHO ที่แนวคิดไม่เคยได้รับการปรับอย่างเต็มที่กับความหลากหลายของภาษาที่รองรับการสืบทอดทั้งอินเทอร์เฟซ (เช่นการพิมพ์ย่อยด้วยอินเทอร์เฟซแท้) และการสืบทอดการใช้งาน มีคนติดตามมนต์นี้มากเกินไปและใช้อินเทอร์เฟซไม่เพียงพอ
Uri

คำตอบ:


136

แม้ว่าฉันคิดว่าฉันเคยได้ยินการสนทนาการแต่งเพลงกับการถ่ายทอดทางพันธุกรรมมานานก่อน GoF แต่ฉันไม่สามารถจับนิ้วมือของฉันบนแหล่งที่มาที่เฉพาะเจาะจง อาจจะมี Booch อยู่ดี

<พูดจาโผงผาง>

อา แต่เหมือนสวดมนต์มากมายสิ่งนี้มีความเสื่อมตามเส้นปกติ:

  1. มันได้รับการแนะนำให้รู้จักกับคำอธิบายโดยละเอียดและการโต้เถียงโดยแหล่งข่าวที่น่านับถือซึ่งเป็นที่จับวลีเพื่อเป็นเครื่องเตือนความทรงจำของการสนทนาที่ซับซ้อนดั้งเดิม
  2. มันถูกแบ่งปันกับการรู้ส่วนหนึ่งของคลับขยิบตาโดยไม่กี่รู้ว่าในขณะที่โดยทั่วไปเมื่อแสดงความคิดเห็นในข้อผิดพลาด n00b
  3. ในไม่ช้ามันก็ซ้ำแล้วซ้ำอีกโดยไม่สนใจคนเป็นพันเป็นพันที่ไม่เคยอ่านคำอธิบาย แต่ความรักที่ใช้มันเป็นข้ออ้างที่จะไม่คิดและเป็นวิธีที่ประหยัดและง่ายต่อการรู้สึกเหนือกว่าผู้อื่น
  4. ในที่สุดจำนวน debunking ที่สมเหตุสมผลไม่สามารถกั้นกระแสน้ำ "meme" - และกระบวนทัศน์เสื่อมโทรมเป็นศาสนาและความเชื่อ

meme เดิมทีตั้งใจจะนำ n00bs ไปสู่การตรัสรู้ตอนนี้ถูกใช้เป็นสโมสรเพื่อกระบองพวกเขาโดยไม่รู้สึกตัว

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

โปรดคิดเกี่ยวกับการออกแบบของคุณและหยุดพ่นคำขวัญ

</ พูดจาโผงผาง>


16
Booch ให้เหตุผลว่าการสืบทอดการใช้งานแนะนำการเชื่อมต่อสูงระหว่างคลาส ในทางกลับกันเขาพิจารณาการสืบทอดแนวคิดหลักที่ทำให้ OOP แตกต่างจากการโปรแกรมเชิงโพรซีเดอร์
Nemanja Trifunovic

13
ควรมีคำสำหรับสิ่งนี้ สำรอกก่อนวัยอันควรอาจจะ?
Jörg W Mittag

8
@ Jörg: คุณรู้หรือไม่ว่าจะเกิดอะไรขึ้นกับคำศัพท์เช่น Premature Regurgitation? สิ่งที่อธิบายไว้ข้างต้น :) (Btw. การสำรอกไม่เคยไม่เกิดก่อนกำหนด?)
Bjarke Freund-Hansen

6
@Nemanja: ถูกต้อง คำถามคือว่าการแต่งงานกันนี้ไม่ดีจริง ๆ หรือไม่ หากชั้นเรียนมีความสัมพันธ์กันอย่างแน่นแฟ้นและก่อให้เกิดความสัมพันธ์แบบ supertype-subtype และไม่สามารถ decoupled อย่างน่าอัศจรรย์แม้ว่าพวกเขาจะแยกทางกันอย่างเป็นทางการในระดับภาษา
dsimcha

5
มนต์นั้นเรียบง่าย "เพียงเพราะคุณสามารถกำหนดให้ play-doh ให้ดูเหมือนว่าอะไรก็ตามที่ไม่ได้หมายความว่าคุณควรทำให้ทุกอย่างหมดไปจาก play-doh" ;)
Evan Plaice

73

ประสบการณ์.

อย่างที่คุณบอกว่ามันเป็นเครื่องมือสำหรับงานต่าง ๆ แต่วลีมาเพราะคนไม่ใช้มันในทางนั้น

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

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


7
ดังนั้นโดยทั่วไปคุณไม่สามารถพูดว่า "คุณไม่ควรใช้ OOP ตั้งแต่แรกถ้าคุณไม่เข้าใจการทดแทน Liskov" ดังนั้นคุณจึงพูดว่า "การจัดองค์ประกอบที่ดีต่อการสืบทอด" แทนเพื่อพยายามจำกัดความเสียหายที่ทำโดยคนไร้ความสามารถ โคด?
Mason Wheeler

13
@ Mason: เหมือนกับมนต์ทุกอย่าง "องค์ประกอบที่โปรดปรานเหนือมรดก" มีจุดมุ่งหมายที่โปรแกรมเมอร์มือใหม่ หากคุณรู้อยู่แล้วว่าจะใช้การสืบทอดและเมื่อใดที่จะใช้การแต่งเพลงก็ไม่เป็นไรที่จะทำซ้ำมนต์เช่นนั้น
Dean Harding

7
@Dean - ฉันไม่แน่ใจว่าเริ่มต้นเหมือนกับคนที่ไม่เข้าใจวิธีปฏิบัติที่ดีที่สุดในการสืบทอด ฉันคิดว่ามันมีมากกว่านั้น การรับมรดกแย่เป็นสาเหตุของอาการปวดหัวจำนวนมากในงานของฉันและมันไม่ใช่รหัสที่เขียนโดยโปรแกรมเมอร์ซึ่งจะถือว่าเป็น "ผู้เริ่มต้น"
นิโคล

6
@Renesis: สิ่งแรกที่ฉันคิดว่าเมื่อฉันได้ยินนั่นคือ "บางคนมีประสบการณ์สิบปีและบางคนมีประสบการณ์หนึ่งปีซ้ำสิบครั้ง"
Mason Wheeler

8
ฉันกำลังออกแบบโครงการขนาดใหญ่พอสมควรหลังจากได้รับ "OO" เป็นครั้งแรกและต้องใช้มันอย่างหนัก แม้ว่ามันจะทำงานได้ดี แต่ฉันพบการออกแบบที่เปราะบาง - ทำให้เกิดการระคายเคืองเล็กน้อยที่นี่และที่นั่นและบางครั้งก็ทำให้ผู้ปรับโครงสร้างบางอย่างเป็นสุนัขที่สมบูรณ์ มันเป็นเรื่องยากที่จะอธิบายประสบการณ์ทั้งหมด แต่วลี "คำตัดสินความโปรดปรานเหนือสิ่งที่สืบทอด" อธิบายไว้อย่างชัดเจน โปรดทราบว่ามันไม่ได้พูดหรือแม้กระทั่งบอกเป็นนัย "หลีกเลี่ยงการรับมรดก" มันเพียง แต่ทำให้คุณสะกิดเล็กน้อยเมื่อตัวเลือกไม่ชัดเจน
Bill K

43

มันไม่ใช่ความคิดใหม่ฉันเชื่อว่ามันถูกนำมาใช้จริงในหนังสือรูปแบบการออกแบบ GoF ซึ่งตีพิมพ์ในปี 1994

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

จากหนังสือ GoF:

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

บทความวิกิพีเดียในหนังสือ GoF มีการแนะนำที่ดี


14
ฉันไม่เห็นด้วยกับสิ่งนั้น คุณไม่จำเป็นต้องรู้รายละเอียดการใช้งานของคลาสที่คุณสืบทอดมา เฉพาะสมาชิกสาธารณะและสมาชิกที่ได้รับความคุ้มครองที่เปิดเผยโดยชั้นเรียน ถ้าคุณต้องรู้รายละเอียดการติดตั้งคุณหรือใครก็ตามที่เขียนคลาสพื้นฐานกำลังทำอะไรผิดพลาดและถ้ามีข้อบกพร่องอยู่ในคลาสพื้นฐานการจัดเรียงจะไม่ช่วยให้คุณแก้ไข / แก้ไขได้
Mason Wheeler

18
คุณไม่เห็นด้วยกับสิ่งที่คุณไม่ได้อ่านอย่างไร มีหน้าทึบและการสนทนาครึ่งหนึ่งจาก GoF ที่คุณได้รับเพียงมุมมองเล็ก ๆ
philosodad

7
@ Phonosodad: ฉันไม่เห็นด้วยกับสิ่งที่ฉันไม่ได้อ่าน ฉันไม่เห็นด้วยกับสิ่งที่ดีนเขียนว่า "ตามคำนิยามคุณต้องรู้รายละเอียดการใช้งานของชั้นเรียนที่คุณสืบทอดมา" ซึ่งฉันได้อ่าน
Mason Wheeler

10
สิ่งที่ฉันเขียนเป็นเพียงบทสรุปของสิ่งที่อธิบายไว้ในหนังสือ GoF ฉันอาจจะได้คำมันน้อยอย่างยิ่ง (คุณไม่จำเป็นต้องรู้ทุกรายละเอียดการดำเนินการ) แต่นั่นคือเหตุผลว่าทำไมทั่วไป GoF กล่าวว่าเพื่อให้ประโยชน์แก่องค์ประกอบมรดก
Dean Harding

2
แก้ไขให้ฉันถ้าฉันผิด แต่ฉันเห็นว่า "ชอบความสัมพันธ์ของคลาสที่ชัดเจน (เช่นการเชื่อมต่อ) ไปที่ปริยาย (เช่นการสืบทอด) อดีตบอกสิ่งที่คุณต้องการโดยไม่บอกวิธีทำ คนหลังนี้ไม่เพียง แต่บอกวิธีการทำ แต่จะทำให้คุณเสียใจ
Evan Plaice

26

เพื่อตอบคำถามของคุณฉันเชื่อว่าแนวคิดนี้ปรากฏตัวครั้งแรกในรูปแบบการออกแบบ GOF : องค์ประกอบของซอฟต์แวร์เชิงวัตถุที่ใช้ซ้ำได้ซึ่งตีพิมพ์ครั้งแรกในปี 1994 วลีปรากฏที่ด้านบนของหน้า 20 ในบทนำ:

ชอบองค์ประกอบของวัตถุมากกว่ามรดก

พวกเขานำหน้าข้อความนี้ด้วยการเปรียบเทียบการสืบทอดสั้น ๆ กับการแต่งเพลง พวกเขาไม่พูดว่า "ไม่เคยใช้มรดก"


23

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

ทำไมเรื่องนี้ถึงเป็นจริง? เนื่องจากการสืบทอดสร้างการเชื่อมต่อแบบรวบรัดเวลาที่กระชับระหว่าง 2 คลาส องค์ประกอบในทางตรงกันข้ามคือการแต่งงานกันอย่างหลวม ๆ ซึ่งจะช่วยให้แยกความกังวลได้อย่างชัดเจนมีความเป็นไปได้ในการสลับการพึ่งพาที่รันไทม์และง่ายขึ้น

นั่นหมายถึงการสืบทอดควรได้รับการจัดการด้วยความระมัดระวังเพราะมีค่าใช้จ่ายไม่ใช่ว่าไม่มีประโยชน์ ที่จริงแล้ว "Composition over inheritance" มักจะจบลงด้วยการเป็น "Composition + inheritance over inheritance" เนื่องจากคุณต้องการให้การพึ่งพาที่สงบของคุณเป็น superclass ที่เป็นนามธรรมแทนที่จะเป็น subclass คอนกรีต ช่วยให้คุณสามารถสลับไปมาระหว่างการใช้งานที่แตกต่างกันของการพึ่งพาของคุณที่รันไทม์

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

ตัวอย่าง (เปรียบเทียบ) อาจเป็น:

"ฉันมีคลาสงูและฉันต้องการรวมเป็นส่วนหนึ่งของคลาสนั้นจะเกิดอะไรขึ้นเมื่องูกัดฉันจะถูกล่อลวงให้งูสืบทอดคลาส BiterAnimal ที่มีวิธีกัด () และแทนที่วิธีนั้นเพื่อสะท้อนพิษที่กัด แต่การเรียงความเรื่องมรดกสืบทอดเตือนฉันว่าฉันควรลองใช้การจัดวางแทน ... ในกรณีของฉันนี่อาจแปลเป็นงูที่มีสมาชิกกัดได้คลาส Bite อาจเป็นนามธรรม (หรืออินเทอร์เฟซ) ที่มีคลาสย่อย ฉันมีสิ่งที่ดีเช่นมี subomlasses ของ VenomousBite และ DryBite และสามารถเปลี่ยนการกัดในตัวอย่างงูตัวเดียวกับที่งูเติบโตอายุบวกกับการจัดการผลกระทบทั้งหมดของ Bite ในชั้นเรียนแยกต่างหากของมันเองทำให้ฉันสามารถนำมันกลับมาใช้ใหม่ได้ เพราะน้ำค้างแข็งกัด แต่ไม่ใช่ BiterAnimal และอื่น ๆ ... "


4
ตัวอย่างที่ดีมากกับงู ฉันได้พบกับกรณีที่คล้ายกันเมื่อเร็ว ๆ นี้กับชั้นเรียนของตัวเอง
Maksee

22

ข้อโต้แย้งที่เป็นไปได้สำหรับการจัดองค์ประกอบ:

องค์ประกอบเป็นภาษา / กรอบความคิดที่ไม่เชื่อเรื่องพระเจ้ามากขึ้น
และสิ่งที่มันบังคับใช้ / ต้องการ / เปิดใช้งานจะแตกต่างกันระหว่างภาษาในแง่ของสิ่งที่ sub / superclass มีการเข้าถึงและสิ่งที่เกี่ยวข้องกับประสิทธิภาพอาจมีวิธีเสมือน การสนับสนุนทางภาษาเพียงเล็กน้อยและการใช้งานข้ามแพลตฟอร์ม / กรอบงานที่แตกต่างกันสามารถแบ่งปันรูปแบบองค์ประกอบได้ง่ายขึ้น

องค์ประกอบเป็นวิธีการสร้างวัตถุที่เรียบง่ายและสัมผัสได้
การรับมรดกค่อนข้างง่ายต่อการเข้าใจ แต่ยังไม่สามารถพิสูจน์ได้อย่างง่ายดายในชีวิตจริง วัตถุจำนวนมากในชีวิตจริงสามารถแบ่งออกเป็นชิ้นส่วนและประกอบด้วย สมมติว่าจักรยานสามารถสร้างขึ้นได้โดยใช้สองล้อเฟรมที่นั่งโซ่ ฯลฯ อธิบายได้อย่างง่ายดายตามองค์ประกอบ ในขณะที่อุปมามรดกคุณสามารถพูดได้ว่าจักรยานขยาย unicycle ค่อนข้างเป็นไปได้ แต่ยังไกลจากภาพจริงมากกว่าการจัดวาง (เห็นได้ชัดว่านี่ไม่ใช่ตัวอย่างมรดกที่ดีมาก แต่ประเด็นยังคงเหมือนเดิม) แม้แต่คำว่ามรดก (อย่างน้อยที่สุดฉันก็คาดหวังว่าจะพูดภาษาอังกฤษ) โดยอัตโนมัติตามความหมายตามบรรทัด "บางสิ่งบางอย่างจากญาติผู้ล่วงลับ" ซึ่งมีความสัมพันธ์กับความหมายในซอฟต์แวร์ แต่ก็ยังพอดีพอดี

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

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

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


1
"เห็นได้ชัดว่ามันไม่ใช่ถนนที่ตัด / ทางเดียว" เมื่อใดการจัดองค์ประกอบไม่ยืดหยุ่น (หรือเท่ากัน) มากกว่าการสืบทอด? ฉันจะยืนยันว่ามันเป็นถนนเดินรถทางเดียว มรดกเป็นเพียงน้ำตาลประโยคสำหรับกรณีพิเศษขององค์ประกอบ
weberc2

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

11

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

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

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

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

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

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


3
เอาล่ะฉันเดาว่ามันสมเหตุสมผลจากมุมมองของ C ++ นั่นคือสิ่งที่ฉันไม่เคยคิดเพราะมันไม่ใช่ปัญหาใน Delphi ซึ่งเป็นสิ่งที่ฉันใช้เวลาส่วนใหญ่ (ไม่มีการสืบทอดหลายอย่างและถ้าคุณมีวิธีการในคลาสพื้นฐานและวิธีอื่นด้วยชื่อเดียวกันในคลาสที่ได้รับซึ่งไม่ได้แทนที่วิธีการพื้นฐานคอมไพเลอร์จะออกคำเตือนดังนั้นคุณจึงไม่ได้ตั้งใจ กับปัญหาแบบนี้)
Mason Wheeler

1
@ Mason: เวอร์ชันของ Object Pascal (หรือ Delphi) ของ Ander นั้นเหนือกว่า C ++ และ Java เมื่อพูดถึงปัญหาการสืบทอดคลาสพื้นฐานที่เปราะบาง ไม่เหมือนกับ C ++ และ Java การโอเวอร์โหลดของวิธีเสมือนที่สืบทอดมานั้นไม่ได้มีความหมายโดยนัย
bit-twiddler

2
@ bit-twiddler สิ่งที่คุณพูดเกี่ยวกับ C ++ และ Java สามารถพูดเกี่ยวกับ Smalltalk, Perl, Python, Ruby, JavaScript, Common LISP, Objective-C และทุกภาษาอื่น ๆ ที่ฉันได้เรียนรู้ที่ให้การสนับสนุน OO ทุกรูปแบบ ที่กล่าวว่า googling แนะนำว่า C # เป็นไปตามการนำของ Object Pascal
btilly

3
นั่นเป็นเพราะ Anders Hejlsberg ได้ออกแบบ Object Pascal (หรือที่รู้จักในชื่อ Delphi) ของ Borland และ C #
bit-twiddler

8

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

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

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

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


"ในสถานการณ์อื่นมรดกจะทำงานได้และองค์ประกอบจะไม่ได้" เมื่อ? การสืบทอดสามารถสร้างแบบจำลองโดยใช้องค์ประกอบและความหลากหลายของอินเทอร์เฟซดังนั้นฉันจะแปลกใจถ้ามีสถานการณ์ใด ๆ ที่องค์ประกอบจะไม่ทำงาน
weberc2

8

นี่คือสองเซ็นต์ของฉัน (นอกเหนือจากจุดที่ยอดเยี่ยมยกแล้ว):

IMHO มันลงมาจากความจริงที่ว่าโปรแกรมเมอร์ส่วนใหญ่ไม่ได้รับมรดกจริง ๆ และจบลงด้วยการหักโหมส่วนหนึ่งเป็นผลมาจากวิธีการสอนแนวคิดนี้ แนวคิดนี้มีอยู่เป็นวิธีที่จะพยายามห้ามปรามพวกเขาจากการทำจนเกินไปแทนที่จะมุ่งเน้นไปที่การสอนพวกเขาถึงวิธีการที่ถูกต้อง

ทุกคนที่ใช้เวลาในการสอนหรือให้คำปรึกษารู้ว่านี่คือสิ่งที่มักจะเกิดขึ้นโดยเฉพาะกับนักพัฒนาใหม่ที่มีประสบการณ์ในกระบวนทัศน์อื่น ๆ :

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

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

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

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

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


นั่นเป็นส่วนที่แท้จริงของการศึกษา คุณต้องทำหลักสูตรที่สูงขึ้นเพื่อรับเช่นส่วนที่เหลืออีก 20% แต่คุณในฐานะนักเรียนได้รับการสอนหลักสูตรขั้นพื้นฐานและบางทีอาจเป็นระดับกลาง ในตอนจบคุณรู้สึกว่าได้รับการสอนอย่างดีเพราะคุณทำหลักสูตรได้ดี (และเพียงแค่ไม่เห็นว่ามันเป็นแค่หมุดบนบันได) มันเป็นเพียงส่วนหนึ่งของความเป็นจริงและทางออกที่ดีที่สุดของเราคือการเข้าใจผลข้างเคียงไม่ใช่โจมตี coders
อิสระ

8

ในตอนหนึ่งของการแสดงความคิดเห็นเมสัน mentionned ว่าวันหนึ่งเราจะพูดเกี่ยวกับมรดกถือว่าเป็นอันตราย

ฉันหวังว่าอย่างนั้น

ปัญหาเกี่ยวกับการสืบทอดนั้นง่ายมากและเป็นอันตรายถึงตายไม่เคารพแนวคิดที่ว่าหนึ่งแนวคิดควรมีฟังก์ชั่นเดียว

ในภาษา OO ส่วนใหญ่เมื่อรับช่วงจากคลาสพื้นฐานคุณ:

  • สืบทอดจากอินเตอร์เฟส
  • สืบทอดมาจากการใช้งาน (ทั้งข้อมูลและวิธีการ)

และนี่คือปัญหา

นี่ไม่ใช่วิธีการเดียวเท่านั้นแม้ว่าภาษา 00 ภาษาส่วนใหญ่จะติดอยู่กับมัน โชคดีที่มีอินเทอร์เฟซ / คลาสนามธรรมอยู่ในนั้น

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

ในฐานะที่เป็นเคาน์เตอร์ - จุดHaskellอนุญาตอนุญาตให้ใช้หลักการ Liskov เมื่อ "ได้รับ" จากอินเทอร์เฟซที่บริสุทธิ์ (เรียกว่าแนวคิด) (1) คุณไม่สามารถสืบทอดมาจากคลาสที่มีอยู่ได้เพียงการแต่งเพลงเท่านั้นที่อนุญาตให้คุณฝังข้อมูล

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


7

คำตอบง่ายๆคือ: การสืบทอดมีการเชื่อมต่อมากกว่าองค์ประกอบ กำหนดตัวเลือกสองอย่างที่มีคุณภาพเทียบเท่ากันให้เลือกตัวเลือกที่มีการจับคู่น้อย


2
แต่นั่นคือประเด็นทั้งหมด พวกเขาไม่ได้ "เทียบเท่าอย่างอื่น" การสืบทอดช่วยให้สามารถทดแทน Liskov และ polymorphism ซึ่งเป็นจุดรวมของการใช้ OOP องค์ประกอบไม่ได้
Mason Wheeler

4
Polymorphism / LSP ไม่ใช่ "จุดรวม" ของ OOP แต่เป็นคุณลักษณะเดียว นอกจากนี้ยังมีการห่อหุ้ม, abstractions ฯลฯ การรับมรดกหมายถึง "เป็น" ความสัมพันธ์รูปแบบการ agregation "มี" ความสัมพันธ์
สตีฟ

@Steve: คุณสามารถทำ abstractions และ encapsulation ในกระบวนทัศน์ใด ๆ ที่สนับสนุนการสร้างโครงสร้างข้อมูลและโพรซีเดอร์ / ฟังก์ชัน แต่ความแตกต่าง (โดยเฉพาะการอ้างถึงวิธีเสมือนจริงในบริบทนี้) และการทดแทน Liskov นั้นมีลักษณะเฉพาะในการเขียนโปรแกรมเชิงวัตถุ นั่นคือสิ่งที่ฉันหมายถึงโดยที่
Mason Wheeler

3
@ Mason: แนวทางคือ "สนับสนุนการแต่งเพลงมากกว่ามรดก" ไม่ได้หมายความว่าจะไม่ใช้หรือหลีกเลี่ยงการสืบทอด ทั้งหมดบอกว่าเมื่อทุกสิ่งเท่าเทียมกันเลือกองค์ประกอบ แต่ถ้าคุณต้องการมรดกให้ใช้มัน!
Jeffrey Faust

7

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

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

มันควรที่จะบอกเป็นนัยว่าเมื่อคุณต้องการมรดกจริงๆมันชัดเจนและคุณควรใช้มัน

นอกจากนี้คำตอบของ Steven Lowe จริงเหรอ


1
ฉันชอบการเปรียบเทียบของคุณ
barrylloyd

2

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

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

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

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


-1

ผมเชื่อว่าคำพูดจริงมาจาก "Effective Java" ของ Joshua Bloch ซึ่งเป็นชื่อของบทใดบทหนึ่ง เขาอ้างว่าการสืบทอดมีความปลอดภัยภายในแพ็คเกจและทุกชั้นเรียนได้รับการออกแบบและจัดทำเอกสารสำหรับการขยายโดยเฉพาะ เขาอ้างว่าตามที่คนอื่น ๆ ระบุไว้การสืบทอดแบ่ง encapsulation เนื่องจากคลาสย่อยขึ้นอยู่กับรายละเอียดการใช้งานของซูเปอร์คลาส สิ่งนี้นำไปสู่ความเปราะบาง

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

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