การสืบทอดกับการรวม [ปิด]


151

มีโรงเรียนคิดสองแห่งเกี่ยวกับวิธีการขยายปรับปรุงและนำโค้ดกลับมาใช้ใหม่ในระบบเชิงวัตถุ:

  1. การสืบทอด: ขยายการทำงานของคลาสโดยการสร้างคลาสย่อย แทนที่สมาชิก superclass ในคลาสย่อยเพื่อมอบฟังก์ชันการทำงานใหม่ สร้างเมธอด abstract / virtual เพื่อบังคับคลาสย่อยให้ "fill-in-the-blanks" เมื่อซูเปอร์คลาสต้องการอินเตอร์เฟสเฉพาะ แต่ไม่เชื่อเรื่องการใช้งาน

  2. การรวม: สร้างฟังก์ชั่นใหม่โดยนำคลาสอื่น ๆ มารวมเข้าด้วยกันในคลาสใหม่ แนบอินเตอร์เฟสทั่วไปเข้ากับคลาสใหม่นี้เพื่อการทำงานร่วมกันกับรหัสอื่น

ประโยชน์ต้นทุนและผลที่ตามมาของแต่ละประเภทคืออะไร มีทางเลือกอื่นหรือไม่?

ฉันเห็นการอภิปรายนี้เกิดขึ้นเป็นประจำ แต่ฉันไม่คิดว่ามันถูกถามใน Stack Overflow เลย (แม้ว่าจะมีการสนทนาที่เกี่ยวข้อง) นอกจากนี้ยังมีการขาดผลลัพธ์ที่ดีของ Google อย่างน่าประหลาดใจ


9
เป็นคำถามที่ดีโชคไม่ดีที่ฉันมีเวลาไม่พอ
Toon Krijthe

4
คำตอบที่ดีนั้นดีกว่าคำตอบที่เร็วกว่า ... ฉันจะเฝ้าดูคำถามของฉันดังนั้นฉันจะโหวตให้คุณอย่างน้อย :-P
Craig Walker

คำตอบ:


181

มันไม่ใช่เรื่องที่ดีที่สุด แต่ควรใช้เมื่อใด

ในกรณี 'ปกติ' คำถามง่าย ๆ ก็เพียงพอที่จะค้นหาว่าเราต้องการการสืบทอดหรือการรวม

  • ถ้าคลาสใหม่นั้นมากหรือน้อยเหมือนคลาสเดิม ใช้การสืบทอด คลาสใหม่ตอนนี้เป็นคลาสย่อยของคลาสดั้งเดิม
  • ถ้าคลาสใหม่ต้องมีคลาสเดิม ใช้การรวม คลาสใหม่ตอนนี้มีคลาสดั้งเดิมในฐานะสมาชิก

อย่างไรก็ตามมีพื้นที่สีเทาขนาดใหญ่ ดังนั้นเราจึงต้องการเทคนิคอื่น ๆ

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

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

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

ให้เพิ่มตัวอย่าง เรามีคลาส 'Dog' พร้อมวิธีการ: 'Eat', 'Walk', 'Bark', 'Play'

class Dog
  Eat;
  Walk;
  Bark;
  Play;
end;

ตอนนี้เราต้องการคลาส 'Cat' ที่ต้องการ 'Eat', 'Walk', 'Purr' และ 'Play' ดังนั้นก่อนอื่นให้พยายามยืดมันออกมาจากสุนัข

class Cat is Dog
  Purr; 
end;

ดูเหมือนจะเป็นไร แต่รอ แมวตัวนี้สามารถเห่าได้ (คนรักแมวจะฆ่าฉันอย่างนั้น) และแมวที่เห่าก็ละเมิดหลักการของจักรวาล ดังนั้นเราจำเป็นต้องแทนที่วิธีการเห่าเพื่อที่จะไม่ทำอะไรเลย

class Cat is Dog
  Purr; 
  Bark = null;
end;

ตกลงใช้งานได้ แต่มันมีกลิ่นไม่ดี ดังนั้นลองรวมกัน:

class Cat
  has Dog;
  Eat = Dog.Eat;
  Walk = Dog.Walk;
  Play = Dog.Play;
  Purr;
end;

ตกลงนี่เป็นสิ่งที่ดี แมวตัวนี้ไม่เห่าอีกต่อไปไม่แม้แต่จะเงียบ แต่ก็ยังมีสุนัขภายในที่ต้องการออก ดังนั้นให้ลองเลขโซลูชันที่สาม:

class Pet
  Eat;
  Walk;
  Play;
end;

class Dog is Pet
  Bark;
end;

class Cat is Pet
  Purr;
end;

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


5
"การใช้งานซ้ำเกือบทุกคลาส" เป็นครั้งเดียวที่ฉันชอบการสืบทอด สิ่งที่ฉันต้องการมันเหมือนเป็นภาษาที่มีความสามารถในการพูดว่า "ตัวแทนวัตถุที่รวบรวมนี้สำหรับวิธีการเหล่านี้เฉพาะที่"; นั่นคือสิ่งที่ดีที่สุดของทั้งสองโลก
Craig Walker

ฉันไม่แน่ใจเกี่ยวกับภาษาอื่น ๆ แต่ Delphi มีกลไกที่ให้สมาชิกใช้ส่วนหนึ่งของอินเทอร์เฟซ
Toon Krijthe

2
วัตถุประสงค์ C ใช้โปรโตคอลที่ให้คุณตัดสินใจได้ว่าจำเป็นต้องใช้ฟังก์ชั่นของคุณหรือไม่ก็ได้
cantfindaname88

1
คำตอบที่ยอดเยี่ยมพร้อมตัวอย่างที่เป็นประโยชน์ ฉันจะออกแบบคลาสสัตว์เลี้ยงด้วยวิธีการที่เรียกmakeSoundและปล่อยให้คลาสย่อยแต่ละคลาสใช้เสียงของตัวเอง สิ่งนี้จะช่วยในสถานการณ์ที่คุณมีสัตว์เลี้ยงมากมายและทำเช่น for_each pet in the list of pets, pet.makeSoundนั้น
blongho


27

ความแตกต่างมักจะแสดงเป็นความแตกต่างระหว่าง "คือ" และ "มี" มรดกที่ "เป็น" ความสัมพันธ์จะสรุปได้เป็นอย่างดีในLiskov ชดเชยหลักการ การรวมความสัมพันธ์ "มี" เป็นเพียงแค่นั้น - มันแสดงให้เห็นว่าวัตถุรวมมีหนึ่งในวัตถุรวม

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


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

ฉันไม่ชอบวิธีการนี้มันเพิ่มเติมเกี่ยวกับองค์ประกอบ
Alireza Rahmani Khalili

15

นี่คือข้อโต้แย้งที่พบบ่อยที่สุดของฉัน:

ในระบบเชิงวัตถุใด ๆ มีสองส่วนในคลาสใด ๆ :

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

  2. ของการดำเนินงาน : ความ "เบื้องหลัง" การทำงานว่าวัตถุที่ไม่เพื่อตอบสนองอินเตอร์เฟซและให้การทำงาน นี่คือรหัสและข้อมูลสมาชิกของวัตถุ

หนึ่งในหลักการพื้นฐานของ OOP คือการใช้งานถูกห่อหุ้ม (เช่น: ซ่อนอยู่) ในชั้นเรียน สิ่งเดียวที่คนนอกควรเห็นคืออินเทอร์เฟซ

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

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

ดังนั้นเมื่อใดก็ตามที่ฉันพัฒนาซอฟต์แวร์เชิงวัตถุฉันมักจะชอบการรวมตัวมากกว่าการสืบทอด


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

หากคุณต้องการอินเทอร์เฟซเพิ่มเติมมากกว่านั้นให้ส่งคืนผ่านวิธีการบนอินเทอร์เฟซของอินเทอร์เฟซแบบ abstracted ระดับหลักล้างซ้ำ
orcmid

คุณคิดว่าการรวมตัวจะดีกว่าในสถานการณ์นี้หรือไม่? หนังสือคือ SellingItem, DigitalDisc เป็น SelliingItem codereview.stackexchange.com/questions/14077/…
LCJ

11

ฉันให้คำตอบ "คือ" vs "Has a": อันไหนดีกว่ากัน? .

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

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

สิ่งเหล่านั้นเป็นเงื่อนงำที่แข็งแกร่งที่การรวมตัวเป็นตัวเลือกที่ดีกว่าในกรณีนั้น


6

ฉันเห็นการตอบสนอง "is-a vs. has-a จำนวนมากพวกเขามีแนวคิดที่แตกต่างกัน" ตอบคำถามนี้และคำถามที่เกี่ยวข้อง

สิ่งหนึ่งที่ฉันพบในประสบการณ์ของฉันคือการพยายามระบุว่าความสัมพันธ์คือ "is-a" หรือ "has-a" ถูกผูกไว้กับความล้มเหลว แม้ว่าคุณจะสามารถกำหนดวัตถุนั้นได้อย่างถูกต้องในขณะนี้ความต้องการในการเปลี่ยนแปลงหมายความว่าคุณอาจผิดในอนาคต

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

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

ดังนั้นคุณมีพายุที่สมบูรณ์แบบของการขัดแย้งกับการสืบทอดเมื่อใดก็ตามที่คุณต้องเลือกอย่างใดอย่างหนึ่ง:

  1. ทางเลือกของคุณน่าจะผิดในบางจุด
  2. การเปลี่ยนตัวเลือกนั้นเป็นเรื่องยากเมื่อคุณตัดสินใจแล้ว
  3. การรับมรดกมีแนวโน้มที่จะเป็นทางเลือกที่แย่กว่าเนื่องจากมีข้อ จำกัด มากกว่า

ดังนั้นฉันมักจะเลือกการรวมตัว - แม้ว่าจะมีความสัมพันธ์ที่แข็งแกร่งก็ตาม


ข้อกำหนดการพัฒนาหมายความว่าการออกแบบ OO ของคุณอาจจะผิด มรดกกับการรวมเป็นเพียงส่วนเล็ก ๆ คุณไม่สามารถออกแบบฟิวเจอร์สที่เป็นไปได้ทั้งหมดดังนั้นเพียงแค่ไปกับแนวคิด XP: แก้ปัญหาข้อกำหนดของวันนี้และยอมรับว่าคุณอาจต้องปรับโครงสร้างใหม่
Bill Karwin

ฉันชอบสายการสอบถามและการซักถามนี้ ความกังวลเกี่ยวกับ blurrung is-a, has-a และ use-a ฉันเริ่มต้นด้วยอินเทอร์เฟซ (พร้อมด้วยการระบุ abstractions ที่ฉันต้องการให้อินเทอร์เฟซ) ระดับทางอ้อมเพิ่มเติมนั้นมีค่ายิ่ง อย่าทำตามข้อสรุปการรวมของคุณ
orcmid

นั่นคือประเด็นของฉัน ทั้งการสืบทอดและการรวมเป็นวิธีการในการแก้ปัญหา หนึ่งในวิธีการเหล่านั้นมีบทลงโทษทุกประเภทเมื่อคุณต้องแก้ปัญหาในวันพรุ่งนี้
Craig Walker

ในใจของฉันการรวม + อินเทอร์เฟซเป็นทางเลือกในการสืบทอด / การทำคลาสย่อย คุณไม่สามารถทำพหุสัณฐานตามการรวมตัวเพียงอย่างเดียว
Craig Walker

3

คำถามนี้มักจะถูกใช้เป็นComposition vs. Inheritanceและมีการถามก่อนหน้านี้


ใช่คุณเป็นคนตลกที่ SO ไม่ได้ให้คำถามนั้นเป็นหนึ่งในคำถามที่เกี่ยวข้อง
Craig Walker

2
การค้นหาดังนั้นยังคงดูดครั้งใหญ่
Vinko Vrsalovic

ตกลง นั่นเป็นเหตุผลที่ฉันไม่ได้ปิดสิ่งนี้ นั่นและผู้คนมากมายได้ตอบไปแล้วที่นี่
Bill the Lizard

1
ดังนั้นต้องการคุณลักษณะในการหมุน 2 คำถาม (และการตอบกลับ) เป็น 1
Craig Walker

3

ฉันต้องการที่จะทำให้ความคิดเห็นเกี่ยวกับคำถามเดิม แต่ 300 ตัวอักษรกัด [; <)

ฉันคิดว่าเราต้องระวัง ครั้งแรกมีรสชาติมากกว่าสองตัวอย่างค่อนข้างเฉพาะที่ทำในคำถาม

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

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

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

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

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


2

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

มรดกที่นี่? มีทะเลหมวกเบเรต์สีเขียวและมือปืน นี่คือประเภททหาร ดังนั้นจึงมีทหารชั้นฐานที่มี Marine, Green Beret & Sniper เป็นคลาสที่ได้รับมา

การรวมที่นี่? เป้สามารถมีระเบิด, ปืน (ประเภทต่าง ๆ ), มีด, medikit ฯลฯ ทหารสามารถติดตั้งสิ่งเหล่านี้ ณ จุดใดก็ตามในเวลาที่กำหนดรวมทั้งเขายังสามารถมีเสื้อเกราะกันกระสุนซึ่งทำหน้าที่เป็นเกราะเมื่อถูกโจมตีและ การบาดเจ็บลดลงถึงร้อยละที่แน่นอน ชั้นทหารมีวัตถุของชั้นเสื้อกั๊กกันกระสุนและชั้นเป้ซึ่งมีการอ้างอิงถึงรายการเหล่านี้


2

ฉันคิดว่ามันไม่ใช่การอภิปราย เป็นเพียงแค่ว่า:

  1. ความสัมพันธ์แบบ is-a (การสืบทอด) เกิดขึ้นน้อยกว่าความสัมพันธ์แบบ has-a (องค์ประกอบ)
  2. การสืบทอดนั้นยากต่อการถูกต้องแม้ว่าจะเหมาะสมที่จะใช้ดังนั้นจึงต้องใช้ความขยันเนื่องจากมันสามารถทำลาย encapsulation กระตุ้นการมีเพศสัมพันธ์อย่างแน่นหนา

ทั้งสองมีที่ของพวกเขา แต่การสืบทอดนั้นมีความเสี่ยง

ถึงแม้ว่ามันจะไม่สมเหตุสมผลเลยที่จะมีคลาส Shape 'having-a' Point and a Square classes นี่คือมรดกที่ครบกำหนด

ผู้คนมักจะคิดถึงมรดกก่อนเมื่อพยายามออกแบบสิ่งที่สามารถขยายได้นั่นคือสิ่งที่ผิด


1

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

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

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


0

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

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

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