Google นำคำถามที่คล้ายกันมาพร้อมกับคำตอบที่ฉันคิดว่าดีมาก ฉันยกมาด้านล่าง
มีความแตกต่างอีกประการที่ซุ่มซ่อนอยู่ที่นี่ซึ่งอธิบายไว้ในบทความเรียงความที่ฉันเชื่อมโยง
วัตถุไม่ได้เป็นวิธีเดียวที่จะใช้นามธรรม ไม่ใช่ทุกสิ่งที่เป็นวัตถุ วัตถุใช้สิ่งที่บางคนเรียกว่าข้อมูลขั้นตอนที่เป็นนามธรรม ชนิดข้อมูลนามธรรมใช้รูปแบบนามธรรมที่แตกต่างกัน
ความแตกต่างหลักปรากฏขึ้นเมื่อคุณพิจารณาวิธีการ / ฟังก์ชั่นไบนารี ด้วยนามธรรมข้อมูลเชิงวัตถุ (วัตถุ) คุณอาจเขียนสิ่งนี้สำหรับอินเทอร์เฟซชุด Int:
interface IntSet {
void unionWith(IntSet s);
...
}
ในตอนนี้ให้พิจารณาการใช้งานของ IntSet สองรายการกล่าวคือรายการที่ได้รับการสนับสนุนโดยรายการและรายการที่ได้รับการสนับสนุนโดยโครงสร้างต้นไม้ไบนารีที่มีประสิทธิภาพมากขึ้น:
class ListIntSet implements IntSet {
void unionWith(IntSet s){ ... }
}
class BSTIntSet implements IntSet {
void unionWith(IntSet s){ ... }
}
ขอให้สังเกตว่า unionWith ต้องใช้อาร์กิวเมนต์ IntSet ไม่ใช่ชนิดที่เจาะจงยิ่งขึ้นเช่น ListIntSet หรือ BSTIntSet ซึ่งหมายความว่าการใช้งาน BSTIntSet ไม่สามารถสันนิษฐานได้ว่าอินพุตนั้นเป็น BSTIntSet และใช้ข้อเท็จจริงนั้นเพื่อให้การใช้งานมีประสิทธิภาพ (มันสามารถใช้ข้อมูลชนิดรันไทม์เพื่อตรวจสอบและใช้อัลกอริทึมที่มีประสิทธิภาพมากขึ้นถ้าเป็นเช่นนั้น แต่ก็ยังสามารถส่ง ListIntSet และต้องถอยกลับไปเป็นอัลกอริทึมที่มีประสิทธิภาพน้อยกว่า)
เปรียบเทียบสิ่งนี้กับ ADTs ซึ่งคุณอาจจะเขียนสิ่งต่อไปนี้ในไฟล์ลายเซ็นหรือส่วนหัว:
typedef struct IntSetStruct *IntSetType;
void union(IntSetType s1, IntSetType s2);
เราตั้งโปรแกรมกับส่วนต่อประสานนี้ ยวดประเภทที่เป็นนามธรรม คุณไม่ได้รู้ว่ามันคืออะไร จากนั้นเรามีการนำ BST ไปใช้งานแล้วให้ประเภทและการดำเนินงานที่เป็นรูปธรรม:
struct IntSetStruct {
int value;
struct IntSetStruct* left;
struct IntSetStruct* right;
}
void union(IntSetType s1, IntSetType s2){ ... }
ตอนนี้สหภาพรู้จริง ๆ แล้วการเป็นตัวแทนที่เป็นรูปธรรมของทั้ง s1 และ s2 ดังนั้นจึงสามารถใช้ประโยชน์จากสิ่งนี้เพื่อการใช้งานที่มีประสิทธิภาพ นอกจากนี้เรายังสามารถเขียนรายการดำเนินการสำรองข้อมูลและเลือกที่จะเชื่อมโยงกับสิ่งนั้นแทน
ฉันได้เขียนไวยากรณ์ C (ish) แล้ว แต่คุณควรดูเช่น Standard ML สำหรับประเภทข้อมูลนามธรรมที่ทำได้อย่างถูกต้อง (ซึ่งคุณสามารถใช้การใช้ ADT ได้มากกว่าหนึ่งรายการในโปรแกรมเดียวกันโดยประมาณด้วย BSTImpl IntSetStruct และ ListImpl.IntSetStruct พูด)
การสนทนานี้เป็นสิ่งที่เป็นนามธรรมข้อมูล (วัตถุ) ช่วยให้คุณสามารถแนะนำการใช้งานใหม่ที่ทำงานร่วมกับคนเก่าของคุณ เช่นคุณสามารถเขียนการใช้งาน LoggingIntSet ที่กำหนดเองของคุณเองและรวมเข้ากับ BSTIntSet แต่นี่คือการแลกเปลี่ยน: คุณสูญเสียประเภทข้อมูลสำหรับวิธีการแบบไบนารี! บ่อยครั้งที่คุณต้องเปิดเผยฟังก์ชั่นการใช้งานและรายละเอียดการใช้งานเพิ่มเติมในอินเทอร์เฟซของคุณมากกว่าการใช้ ADT ตอนนี้ฉันรู้สึกเหมือนฉันกำลังพิมพ์เรียงความ Cook อีกครั้งดังนั้นจริง ๆ อ่านมัน!
ฉันต้องการเพิ่มตัวอย่างให้กับสิ่งนี้
Cook แสดงให้เห็นว่าตัวอย่างของประเภทข้อมูลนามธรรมเป็นโมดูลใน C แน่นอนว่าโมดูลใน C เกี่ยวข้องกับการซ่อนข้อมูลเนื่องจากมีฟังก์ชั่นสาธารณะที่ส่งออกผ่านไฟล์ส่วนหัวและฟังก์ชั่นคงที่ (ส่วนตัว) ที่ไม่ นอกจากนี้มักจะมีคอนสตรัคเตอร์ (เช่น list_new ()) และผู้สังเกตการณ์ (เช่น list_getListHead ())
จุดสำคัญของสิ่งที่ทำให้พูดรายการโมดูลที่เรียกว่า LIST_MODULE_SINGLY_LINKED ADT ก็คือฟังก์ชั่นของโมดูล (เช่น list_getListHead ()) ถือว่าข้อมูลที่ป้อนเข้านั้นถูกสร้างขึ้นโดยนวกรรมิกของ LIST_MODULE_SINGLY_LINKED "การใช้งานรายการ (เช่น LIST_MODULE_DYNAMIC_ARRAY) ซึ่งหมายความว่าฟังก์ชั่นของ LIST_MODULE_SINGLY_LINKED สามารถสันนิษฐานได้ว่าในการนำไปใช้งานของพวกเขานั้นจะเป็นการแสดงเฉพาะ (เช่นรายการที่เชื่อมโยงโดยลำพัง)
LIST_MODULE_SINGLY_LINKED ไม่สามารถทำงานร่วมกับ LIST_MODULE_DYNAMIC_ARRAY เนื่องจาก LIST_MODULE_SEDED_LINKEDEDEDEDEDEDEDED เนื่องจาก LIST_MODULE_SING_LINK รายการ LIST_MODULE_SING_LINK สำหรับ LIST_MODULE_SING_LINK รายการ LIST_MODULE_SING_LINK เนื่องจาก LIST_MODULE_SING_LINK รายการ LIST_MODULE_SING_LINK สำหรับ LIST_MODULE_SING_LINK รายการ LIST_MODULE_SING_LINK รายการ LIST_MODULE_SINGLY_LINKED รายการ LIST_MODULE_SINGLY_LINKED
นี่คล้ายกับวิธีที่สองกลุ่มที่แตกต่างจากพีชคณิตนามธรรมไม่สามารถทำงานร่วมกันได้ (นั่นคือคุณไม่สามารถใช้ผลิตภัณฑ์ขององค์ประกอบของกลุ่มหนึ่งที่มีองค์ประกอบของกลุ่มอื่น) นี่เป็นเพราะกลุ่มถือว่าคุณสมบัติการปิดของกลุ่ม (ผลิตภัณฑ์ขององค์ประกอบในกลุ่มจะต้องอยู่ในกลุ่ม) อย่างไรก็ตามหากเราสามารถพิสูจน์ได้ว่ากลุ่มที่แตกต่างกันสองกลุ่มเป็นกลุ่มย่อยจริง ๆ ของกลุ่ม G อีกกลุ่มจากนั้นเราสามารถใช้ผลิตภัณฑ์ของ G เพื่อเพิ่มองค์ประกอบสองกลุ่มหนึ่งกลุ่มจากแต่ละกลุ่ม
เปรียบเทียบ ADT และวัตถุ
Cook ผูกความแตกต่างระหว่าง ADT และวัตถุบางส่วนกับปัญหาการแสดงออก. พูดอย่างคร่าวๆ ADT นั้นประกอบเข้ากับฟังก์ชั่นทั่วไปที่มักจะนำมาใช้ในภาษาโปรแกรมการทำงานในขณะที่ออบเจ็กต์จะถูกจับคู่กับ Java "ออบเจ็กต์" ที่เข้าถึงผ่านอินเตอร์เฟส สำหรับวัตถุประสงค์ของข้อความนี้ฟังก์ชั่นทั่วไปเป็นฟังก์ชั่นที่ใช้ในการขัดแย้ง ARGS และประเภท TYPE (เงื่อนไขล่วงหน้า); มันขึ้นอยู่กับประเภทมันเลือกฟังก์ชั่นที่เหมาะสมและประเมินด้วย ARGS (หลังเงื่อนไข) ทั้งฟังก์ชั่นทั่วไปและวัตถุใช้ความหลากหลาย แต่ด้วยฟังก์ชั่นทั่วไปโปรแกรมเมอร์รู้ว่าฟังก์ชั่นจะถูกดำเนินการโดยฟังก์ชั่นทั่วไปโดยไม่ต้องดูรหัสของฟังก์ชั่นทั่วไป ด้วยวัตถุในทางกลับกันโปรแกรมเมอร์ไม่ทราบว่าวัตถุจะจัดการกับอาร์กิวเมนต์อย่างไรเว้นแต่โปรแกรมเมอร์จะดูที่รหัสของวัตถุ
โดยทั่วไปแล้วปัญหาเรื่องการแสดงออกเป็นสิ่งที่คิดในแง่ของ "ฉันมีการเป็นตัวแทนมากมาย" เมื่อเทียบกับ "ฉันมีฟังก์ชั่นมากมายพร้อมการแสดงจำนวนเล็กน้อย" ในกรณีแรกคุณควรจัดระเบียบรหัสโดยแสดง (ตามที่พบมากที่สุดโดยเฉพาะใน Java) ในกรณีที่สองหนึ่งควรจัดระเบียบรหัสตามฟังก์ชั่น (เช่นมีฟังก์ชั่นทั่วไปเดียวจัดการหลายตัวแทน)
หากคุณจัดระเบียบรหัสของคุณด้วยการเป็นตัวแทนดังนั้นหากคุณต้องการเพิ่มฟังก์ชันการทำงานพิเศษคุณจะถูกบังคับให้เพิ่มฟังก์ชันการทำงานให้กับการแสดงวัตถุทุกครั้ง ในแง่นี้ฟังก์ชั่นการเพิ่มไม่ได้เป็น "สารเติมแต่ง" หากคุณจัดระเบียบโค้ดตามหน้าที่การใช้งานหากคุณต้องการเพิ่มการแทนพิเศษ - คุณจะถูกบังคับให้เพิ่มการแทนลงในทุกวัตถุ ในแง่นี้การเพิ่มการเป็นตัวแทนไม่ใช่ "การเติมแต่ง"
ข้อได้เปรียบของ ADT บนวัตถุ
การเพิ่มฟังก์ชั่นเป็นสารเติมแต่ง
เป็นไปได้ที่จะยกระดับความรู้เกี่ยวกับการเป็นตัวแทนของ ADT สำหรับการปฏิบัติงานหรือเพื่อพิสูจน์ว่า ADT จะรับประกันว่าการเลื่อนตำแหน่งบางครั้งจะมีเงื่อนไขเบื้องต้น ซึ่งหมายความว่าการเขียนโปรแกรมด้วย ADT นั้นเกี่ยวกับการทำสิ่งที่ถูกต้องในลำดับที่ถูกต้อง (ผูกมัดล่วงหน้าเงื่อนไขและโพสต์เงื่อนไขสู่เงื่อนไขการโพสต์ "เป้าหมาย")
ข้อดีของวัตถุมากกว่า ADT
การเพิ่มการเป็นตัวแทนในการเสริม
วัตถุสามารถทำงานระหว่างกันได้
เป็นไปได้ที่จะระบุเงื่อนไขก่อน / หลังสำหรับวัตถุและเชื่อมโยงสิ่งเหล่านี้เข้าด้วยกันเช่นเดียวกับกรณีของ ADT ในกรณีนี้ข้อดีของวัตถุคือ (1) เปลี่ยนการรับรองได้ง่ายโดยไม่ต้องเปลี่ยนส่วนต่อประสานและ (2) วัตถุสามารถทำงานร่วมกันได้ อย่างไรก็ตามสิ่งนี้เอาชนะจุดประสงค์ของ OOP ในแง่ของ smalltalk (ดูหัวข้อ "OOP เวอร์ชันของ Alan Kay ของ OOP)
การจัดส่งแบบไดนามิกเป็นกุญแจสำคัญใน OOP
มันควรจะชัดเจนแล้วในขณะนี้ว่าการกระจายแบบไดนามิก (เช่นการรวมล่าช้า) เป็นสิ่งจำเป็นสำหรับการเขียนโปรแกรมเชิงวัตถุ นี่คือเพื่อให้เป็นไปได้ในการกำหนดขั้นตอนในลักษณะทั่วไปที่ไม่ถือว่าเป็นตัวแทนเฉพาะ การที่จะเป็นรูปธรรม - การเขียนโปรแกรมเชิงวัตถุนั้นง่ายในไพ ธ อนเพราะมันเป็นไปได้ที่วิธีการโปรแกรมของอ็อบเจกต์ในแบบที่ไม่ถือว่าเป็นการแทนเฉพาะ นี่คือเหตุผลที่หลามไม่ต้องการอินเตอร์เฟสเช่น Java
ใน Java คลาสคือ ADT อย่างไรก็ตามคลาสที่เข้าถึงได้ผ่านส่วนต่อประสานที่ใช้นั้นเป็นวัตถุ
ภาคผนวก: OOP เวอร์ชันของ Alan Kay
อลันเคย์เรียกวัตถุอย่างชัดเจนว่า "ครอบครัวของจีบราส์" และแม่ครัวแนะนำว่า ADT เป็นพีชคณิต ดังนั้นเคย์น่าจะหมายความว่าวัตถุนั้นเป็นตระกูลของ ADT นั่นคือวัตถุคือชุดของคลาสทั้งหมดที่เป็นไปตามอินเตอร์เฟส Java
อย่างไรก็ตามรูปภาพของวัตถุที่วาดโดย Cook นั้นมีข้อ จำกัด มากกว่าวิสัยทัศน์ของ Alan Kay เขาต้องการให้วัตถุทำงานเป็นคอมพิวเตอร์ในเครือข่ายหรือเป็นเซลล์ชีวภาพ แนวคิดคือการใช้หลักการของความมุ่งมั่นน้อยที่สุดในการเขียนโปรแกรม - เพื่อให้ง่ายต่อการเปลี่ยนเลเยอร์ระดับต่ำของ ADT เมื่อเลเยอร์ระดับสูงถูกสร้างขึ้นโดยใช้พวกเขา เมื่อนึกภาพนี้แล้วอินเทอร์เฟซ Java นั้นเข้มงวดเกินไปเพราะไม่อนุญาตให้วัตถุตีความความหมายของข้อความหรือไม่สนใจเลย
โดยสรุปความคิดหลักของวัตถุสำหรับเคย์ - ไม่ใช่ว่าพวกเขาเป็นตระกูลของจีบราส์ (ตามที่ Cook เน้น) แต่แนวคิดหลักของ Kay คือการใช้แบบจำลองที่ทำงานในคอมพิวเตอร์ขนาดใหญ่ (คอมพิวเตอร์ในเครือข่าย) กับวัตถุขนาดเล็ก (วัตถุในโปรแกรม)
แก้ไข: การทำให้กระจ่างอีกครั้งใน OOP เวอร์ชันของ Kay: วัตถุประสงค์ของวัตถุคือการเข้าใกล้อุดมคติที่เปิดเผย เราควรบอกวัตถุว่าต้องทำอย่างไร - อย่าบอกว่าการทำ micromanaging เป็นสถานะเช่นเดียวกับจารีตประเพณีของการเขียนโปรแกรมเชิงปฏิบัติและ ADT ข้อมูลเพิ่มเติมสามารถพบได้ที่นี่ , ที่นี่ , ที่นี่และที่นี่
แก้ไข: ผมพบว่าการแสดงออกมากดีมากของคำนิยามอลันเคย์ของ OOP ที่นี่