การชอบแต่งเพลงไม่ได้เป็นเพียงเรื่องของความหลากหลาย แม้ว่ามันจะเป็นส่วนหนึ่งของมันและคุณก็ถูกต้อง (อย่างน้อยในภาษาที่พิมพ์ชื่อ) สิ่งที่ผู้คนหมายถึงจริงๆคือ "ชอบการผสมผสานระหว่างองค์ประกอบและการใช้อินเทอร์เฟซ" แต่เหตุผลที่ชอบองค์ประกอบ (ในหลาย ๆ สถานการณ์) นั้นลึกซึ้ง
ความแตกต่างเป็นเรื่องเกี่ยวกับสิ่งหนึ่งที่ประพฤติหลายวิธี ดังนั้นข้อมูลทั่วไป / แม่แบบเป็นคุณสมบัติ "polymorphic" ในขณะที่พวกเขาอนุญาตให้ชิ้นส่วนของรหัสที่แตกต่างกันพฤติกรรมการทำงานกับประเภท อันที่จริงแล้วความหลากหลายชนิดนี้เป็นพฤติกรรมที่ดีที่สุดและโดยทั่วไปเรียกว่าตัวแปรหลายรูปแบบเนื่องจากการเปลี่ยนแปลงถูกกำหนดโดยพารามิเตอร์
หลายภาษาจัดให้มีรูปแบบของความหลากหลายที่เรียกว่า "การบรรทุกเกินพิกัด" หรือpolocorphism แบบเฉพาะกิจที่กระบวนการหลายอย่างที่มีชื่อเดียวกันถูกกำหนดไว้ในลักษณะที่เฉพาะกิจและที่หนึ่งถูกเลือกโดยภาษา นี่เป็นรูปแบบที่มีความหลากหลายน้อยที่สุดเนื่องจากไม่มีสิ่งใดที่เชื่อมโยงพฤติกรรมของทั้งสองกระบวนการยกเว้นการประชุมที่ได้รับการพัฒนา
ชนิดที่สามของความแตกต่างเป็นชนิดย่อย polymorphism นี่คือขั้นตอนที่กำหนดไว้ในประเภทที่กำหนดนอกจากนี้ยังสามารถทำงานกับทั้งครอบครัว "ประเภทย่อย" ของประเภทนั้น เมื่อคุณใช้อินเทอร์เฟซหรือขยายคลาสคุณมักจะประกาศความตั้งใจในการสร้างชนิดย่อย ชนิดย่อยที่แท้จริงถูกควบคุมโดยหลักการทดแทนของ Liskovซึ่งบอกว่าถ้าคุณสามารถพิสูจน์บางสิ่งเกี่ยวกับวัตถุทั้งหมดใน supertype คุณสามารถพิสูจน์ได้เกี่ยวกับอินสแตนซ์ทั้งหมดในชนิดย่อย ชีวิตจะได้รับอันตรายแม้ว่าในภาษาอย่าง C ++ และ Java คนทั่วไปจะไม่มีการบังคับใช้และมักจะไม่มีสมมติฐานเกี่ยวกับคลาสที่อาจหรืออาจไม่เป็นจริงเกี่ยวกับคลาสย่อยของพวกเขา นั่นคือรหัสจะถูกเขียนราวกับว่าสามารถพิสูจน์ได้มากกว่าที่เป็นจริงซึ่งก่อให้เกิดปัญหามากมายเมื่อคุณพิมพ์ย่อยอย่างไม่ระมัดระวัง
การสืบทอดนั้นเป็นอิสระจากความแตกต่าง เมื่อพิจารณาถึงสิ่ง "T" ซึ่งมีการอ้างอิงถึงตัวเองการสืบทอดจะเกิดขึ้นเมื่อคุณสร้างสิ่งใหม่ "S" จาก "T" แทนที่ "T" แทนการอ้างอิงถึงตัวเองด้วยการอ้างอิงถึง "S" คำจำกัดความนั้นคลุมเครือเนื่องจากการสืบทอดสามารถเกิดขึ้นได้ในหลายสถานการณ์ แต่สิ่งที่พบได้บ่อยที่สุดคือการทำ subclassing วัตถุซึ่งมีผลในการแทนที่this
ตัวชี้ที่เรียกโดยฟังก์ชันเสมือนด้วยthis
ตัวชี้ไปยังชนิดย่อย
การรับมรดกเป็นสิ่งอันตรายเช่นเดียวกับสิ่งที่มีประสิทธิภาพมากการสืบทอดมีพลังในการทำให้เกิดความเสียหาย ตัวอย่างเช่นสมมติว่าคุณแทนที่เมธอดเมื่อสืบทอดจากคลาสบางคลาส: ทั้งหมดดีและดีจนกระทั่งเมธอดอื่นของคลาสนั้นใช้วิธีที่คุณสืบทอดมาเพื่อให้ทำงานในลักษณะที่แน่นอน . คุณสามารถป้องกันได้บางส่วนด้วยการประกาศวิธีการทั้งหมดที่เรียกใช้โดยวิธีการอื่นของคุณทั้งแบบส่วนตัวและไม่ใช่แบบเสมือน (ขั้นสุดท้าย) เว้นแต่จะได้รับการออกแบบมาให้แทนที่ แม้ว่าสิ่งนี้จะไม่ดีพอเสมอไป บางครั้งคุณอาจเห็นสิ่งนี้ (ในหลอก Java หวังว่าผู้อ่าน C ++ และ C # จะอ่านได้)
interface UsefulThingsInterface {
void doThings();
void doMoreThings();
}
...
class WayOfDoingUsefulThings implements UsefulThingsInterface{
private foo stuff;
public final int getStuff();
void doThings(){
//modifies stuff, such that ...
...
}
...
void doMoreThings(){
//ignores stuff
...
}
}
คุณคิดว่าสิ่งนี้น่ารักและมีวิธีการทำ "สิ่งต่าง ๆ " ของคุณเอง แต่คุณใช้การสืบทอดเพื่อรับความสามารถในการทำ "สิ่งอื่น ๆ "
class MyUsefulThings extends WayOfDoingUsefulThings{
void doThings {
//my way
}
}
และทุกอย่างดีและดี WayOfDoingUsefulThings
ได้รับการออกแบบในลักษณะที่แทนที่หนึ่งวิธีจะไม่เปลี่ยนซีแมนทิกส์ของวิธีการอื่น ... ยกเว้นรอไม่เป็น ดูเหมือนว่ามันเป็น แต่doThings
เปลี่ยนสถานะที่ไม่แน่นอนที่มีความสำคัญ ดังนั้นแม้ว่ามันจะไม่เรียกใช้ฟังก์ชันแทนที่ใด ๆ
void dealWithStuff(WayOfDoingUsefulThings bar){
bar.doThings()
use(bar.getStuff());
}
MyUsefulThings
ตอนนี้ทำอะไรบางอย่างที่แตกต่างกันกว่าที่คาดไว้เมื่อคุณผ่านมัน อะไรที่แย่กว่านั้นคือคุณอาจไม่รู้ด้วยซ้ำว่าWayOfDoingUsefulThings
ทำตามสัญญา อาจdealWithStuff
มาจากห้องสมุดเดียวกันWayOfDoingUsefulThings
และgetStuff()
ไม่ได้ส่งออกโดยห้องสมุด (คิดว่าเป็นเพื่อนชั้นเรียนใน C ++) ที่แย่กว่านั้นคือคุณได้เอาชนะการตรวจสอบแบบคงที่ของภาษาโดยที่ไม่รู้ตัว: dealWithStuff
ใช้เวลาWayOfDoingUsefulThings
เพียงเพื่อให้แน่ใจว่ามันจะมีgetStuff()
ฟังก์ชั่นที่ทำงานได้ดี
ใช้องค์ประกอบ
class MyUsefulThings implements UsefulThingsInterface{
private way = new WayOfDoingUsefulThings()
void doThings() {
//my way
}
void doMoreThings() {
this.way.doMoreThings();
}
}
นำกลับมาความปลอดภัยประเภทคงที่ โดยทั่วไปการใช้งานง่ายกว่าและปลอดภัยกว่าการสืบทอดเมื่อใช้งานการพิมพ์ย่อย นอกจากนี้ยังช่วยให้คุณสามารถแทนที่วิธีสุดท้ายซึ่งหมายความว่าคุณควรประกาศทุกอย่างสุดท้าย / ไม่เสมือนยกเว้นในส่วนต่อประสานส่วนใหญ่ของเวลา
ในโลกที่ดีกว่าภาษาจะแทรกแผ่นสำเร็จรูปด้วยdelegation
คำหลักโดยอัตโนมัติ ส่วนใหญ่ไม่เช่นนั้นข้อเสียคือชั้นเรียนที่ใหญ่กว่า แม้ว่าคุณจะสามารถทำให้ IDE ของคุณเขียนอินสแตนซ์การมอบหมายให้คุณได้
ตอนนี้ชีวิตไม่ได้เป็นเพียงเกี่ยวกับความหลากหลาย คุณไม่จำเป็นต้องพิมพ์ย่อยตลอดเวลา เป้าหมายของความหลากหลายคือการใช้รหัสซ้ำแต่ไม่ใช่วิธีเดียวที่จะบรรลุเป้าหมายนั้น บ่อยครั้งที่ทำให้รู้สึกถึงการใช้องค์ประกอบโดยไม่ต้องมีความแตกต่างหลากหลายชนิดเป็นวิธีการจัดการฟังก์ชั่น
นอกจากนี้ยังมีการสืบทอดพฤติกรรมที่มีการใช้งาน มันเป็นหนึ่งในความคิดที่ทรงพลังที่สุดในวิทยาการคอมพิวเตอร์ เพียงแค่นั้นส่วนใหญ่แล้วแอปพลิเคชั่น OOP ที่ดีสามารถเขียนได้โดยใช้เพียงการสืบทอดส่วนต่อประสานและองค์ประกอบ หลักการสองข้อ
- ห้ามการสืบทอดหรือการออกแบบสำหรับมัน
- ชอบองค์ประกอบ
เป็นแนวทางที่ดีสำหรับเหตุผลข้างต้นและไม่ต้องเสียค่าใช้จ่ายจำนวนมาก