ประโยชน์ของการเขียนโปรแกรมเชิงวัตถุบนการเขียนโปรแกรมตามขั้นตอนคืออะไร


77

ฉันพยายามที่จะเข้าใจความแตกต่างระหว่างภาษาเชิงปฏิบัติเช่น C และภาษาเชิงวัตถุเช่น C ++ ฉันไม่เคยใช้ C ++ แต่ฉันได้คุยกับเพื่อน ๆ เกี่ยวกับวิธีแยกแยะทั้งสอง

ฉันได้รับการบอกว่า C ++ มีแนวคิดเชิงวัตถุเช่นเดียวกับโหมดสาธารณะและส่วนตัวสำหรับการกำหนดตัวแปร: สิ่งที่ C ไม่มี ฉันไม่เคยใช้สิ่งเหล่านี้ในขณะที่กำลังพัฒนาโปรแกรมใน Visual Basic.NET: ประโยชน์ของสิ่งเหล่านี้คืออะไร?

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

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

if ( login == "admin") {
    // invoke the function
}

ทำไมสิ่งนี้จึงไม่เหมาะ

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




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

14
@DXM ความคิดที่ยอดเยี่ยม! ลูกศร Downvote / upvote ที่ลอยอยู่รอบ ๆ ผู้ร่วมงาน ... นั่นจะเป็นสิ่งมหัศจรรย์
yannis

2
อาร์กิวเมนต์ตัวนับมาตรฐาน: นอกจากนี้ยังมีวิธีการประกอบที่จะทำทุกสิ่งที่คุณสามารถทำได้ใน C ดังนั้นทำไมคุณควรใส่ใจกับ C? (คำแนะนำ: มันคือทั้งหมดที่เกี่ยวกับการเพิ่ม t เขาระดับของนามธรรม c ++ พอที่จะทำเช่นนี้กับการเสียสละมากที่สุดของความเร็ว C ของ IMO นั่นเป็นเหตุผลหลักสำหรับความสำเร็จ c ++'...)
เอสบีไอ

คำตอบ:


135

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

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

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

ฉันคิดว่าคำถามพื้นฐานที่คุณต้องตอบคือ: "ทำไมฉันจึงต้องการซ่อนข้อมูลหรือไม่ถ้าฉันทำอย่างนั้นฉันจะไม่สามารถทำงานกับมันได้!" และนี่คือเหตุผล:

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

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

สิ่งที่ฉันอธิบายไว้ข้างต้นเป็นตัวอย่างของรหัสคู่ที่สมบูรณ์แบบ และนับตั้งแต่รุ่งอรุณของเวลา (สมมติว่าเวลาเริ่ม 1 มกราคม 1970) ชนิดของมนุษย์ได้มองหาวิธีที่จะหลีกเลี่ยงปัญหาเหล่านี้ วิธีที่คุณหลีกเลี่ยงได้คือการแบ่งรหัสของคุณออกเป็นระบบระบบย่อยและส่วนประกอบและ จำกัด จำนวนหน้าที่การเข้าถึงข้อมูลส่วนใด ๆ ถ้าฉันมีจำนวนเต็ม 5 ตัวและสตริงที่เป็นตัวแทนของสถานะบางอย่างฉันจะทำงานกับสถานะนี้ได้ง่ายขึ้นหรือไม่ถ้ามีเพียง 5 ฟังก์ชันตั้งค่า / รับค่า หรือถ้าตั้งค่า 100 ฟังก์ชัน / รับค่าเหล่านี้? แม้จะไม่มีภาษา OO (เช่น C) ผู้คนก็ทำงานกันอย่างหนักในการแยกข้อมูลจากข้อมูลอื่นและสร้างขอบเขตการแยกที่สะอาดระหว่างส่วนต่าง ๆ ของรหัส เมื่อโครงการมีขนาดที่แน่นอนความง่ายในการเขียนโปรแกรมจะไม่กลายเป็น "ฉันสามารถเข้าถึงตัวแปร X จากฟังก์ชัน Y"

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

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


5
คำตอบที่ดีดูเหมือนว่าจะเข้าสู่ระดับที่เหมาะสมตามคำถาม
Carlos

29
+1 ... ส่วนใหญ่สำหรับ "และตั้งแต่รุ่งอรุณของเวลา (สมมติว่าเวลาเริ่ม 1 มกราคม 1970) ... " บรรทัด
CaffGeek

4
@Chad - ฉันถูกหาบรรทัดที่อยู่คนเดียวควรจะทำคะแนนให้ผมอย่างน้อยหนึ่งจุด :)
DXM

มีวิธีจัดการกับปัญหาของขนาดนี้ที่คุณพูดถึงในกระบวนทัศน์กระบวนงาน มันเรียกว่าฟังก์ชั่น แต่วิธีที่ดีในการอธิบายปัญหา
รำคาญ

@DXM - ฉันไม่แน่ใจว่าฉันเข้าใจคำตอบถูกต้องหรือไม่ เราสามารถบรรลุการตั้งค่า / รับฟังก์ชั่นเดียวกันในขั้นตอนการเขียนโปรแกรมด้วย เราสามารถเขียนฟังก์ชั่น set / get ใน C เพื่อแก้ไข / รับค่าตัวแปรโกลบอล การใช้วิธีนี้เรายัง จำกัด จำนวนฟังก์ชั่นที่กำลังแก้ไขตัวแปรทั่วโลก และแม้แต่ใน OOP ถ้าเราใช้เมธอด set / get ด้วยเราจะใช้เมธอดเหล่านี้จากนอกวัตถุเพื่อเปลี่ยนค่า
kadina

10

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

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

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

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


6

OOP กับ C ไม่ได้เกี่ยวกับสิ่งที่คุณพูดถึง ส่วนใหญ่เกี่ยวกับรหัสบรรจุภัณฑ์ในพื้นที่ที่จะไม่ / ไม่สามารถไม่ได้ตั้งใจ (หรือบางครั้งอาจมีเจตนา) ส่งผลกระทบต่อกันและกัน

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


4
-1 ไม่มีอะไรพิเศษใน C ที่ทำให้ฟังก์ชั่นทั้งหมดเป็นสากล คุณสามารถประกาศฟังก์ชั่นใด ๆ คงที่และ จำกัด ขอบเขตของมันเป็นไฟล์ท้องถิ่น C ไม่แตกต่างจาก C ++, Java และอื่น ๆ ในด้านนี้ นอกจากนี้ OOP ไม่เกี่ยวกับไวยากรณ์ภาษาคุณสามารถเขียนโปรแกรม OO ใน C ได้ดีแม้ว่ามันจะค่อนข้างหยาบกว่าในภาษาที่มีการสนับสนุนทางไวยากรณ์สำหรับ OO และตรงกันข้าม: คุณไม่ได้รับ OOP เพียงเพราะคุณเลือกภาษาที่รองรับ OO การวางแนววัตถุเป็นลักษณะการเขียนโปรแกรมไม่ใช่คุณสมบัติทางภาษา

@Lundin: ในขณะที่คุณถูกต้องทางเทคนิคคุณได้พลาดจุด ภาษาของ OOP ทำให้เป็นพฤติกรรมเริ่มต้นที่จะประพฤติในลักษณะ OOP C ไม่ได้
John Fisher

1
ไม่มีสิ่งใดในภาษา OO ที่บังคับให้คุณทำเช่นนั้น ตัวอย่างเช่นฉันได้เห็นโปรแกรม C ++ ที่คลุมเครือนับไม่ถ้วนโดยไม่ต้องพูดถึง OO ในทำนองเดียวกันถ้าคุณไม่มีเงื่อนงำเกี่ยวกับ OO แต่พยายามใช้คลาส, มรดก ฯลฯ มีโอกาสประมาณ 100% ในการสร้างโปรแกรม messed-up

@Lundin: ฉันไม่คิดว่า C ++ เป็นตัวอย่างที่ดี มันคือ (หรืออย่างน้อยก็) หมายถึงการสามารถรวบรวมโปรแกรม C โดยไม่ต้องดัดแปลงมากนัก การเพิ่มคลาสที่ด้านบนไม่ได้ทำให้เป็นภาษา OOP ในระดับ C # หรือ Java แต่จะเปิดใช้งานการพัฒนาประเภทนั้น
John Fisher

คุณสามารถเขียนโปรแกรมที่ไม่ใช่ OO ใน Java ได้เช่นกันเพียงแค่ตัดไฟล์หลักขนาดใหญ่หนึ่งไฟล์ ... OO ยังไม่เจาะจงภาษาหากโปรแกรมเมอร์ไม่รู้จัก OO ไม่มีภาษาใดในโลกที่จะช่วยพวกเขาได้

4

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

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

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


แนวคิดของอินเทอร์เฟซไม่ซ้ำกันกับภาษาเชิงวัตถุ ฉันคิดว่าปัจจัยที่ใหญ่กว่านั้นคือในภาษาที่ไม่ใช่ OOP ฟังก์ชั่นเกือบทั้งหมดที่ใช้ภายในโมดูลจะต้องเป็นของเนมสเปซส่วนกลางเดียวกัน สิ่งนี้ต้องการให้ชื่อฟังก์ชันคำนำหน้าอย่างใดอย่างหนึ่งระบุว่าพวกเขาทำอะไรหรือมีวิธีการทำให้เกิดเสียงที่คล้ายกันหลายอย่างซึ่งทำสิ่งที่แตกต่างอย่างสิ้นเชิง (เช่นSetLocationอาจใช้เพื่อย้าย a Monsterในขณะที่SetPositionอาจย้าย a PopupWindowและMoveอาจใช้เพื่อปรับตำแหน่ง ของDisplayCursor) พยายามที่จะหาทางขวา "ย้าย" วิธีการ ...
SuperCat

... สามารถทำได้ง่ายขึ้นถ้าเมื่อผู้เขียนMyMonstor->แก้ไขจะแสดงรายการวิธีการที่ใช้ได้กับสิ่งที่พิมพ์Monsterเท่านั้น หากมีหลายสิ่งหลายอย่างที่แตกต่างกันซึ่งแต่ละอย่างรองรับการทำงานของโหลการตัดจำนวนของความยุ่งเหยิงในรายการวิธี 90% สามารถลดความยุ่งยากในการผลิตได้อย่างมาก
supercat

@supercat การปะทะกันของชื่อเป็นปัญหาทางภาษาไม่ใช่ปัญหาที่ไม่ใช่ของ OOP ในทางตรงกันข้ามเนมสเปซนั้นมีปัญหาเพราะคอมไพเลอร์จำเป็นต้องเปลี่ยนชื่อฟังก์ชั่นโดยอัตโนมัติหรือทำให้มันยุ่งเหยิง ดังนั้นทำไมไม่เพียงทำด้วยตนเอง
รำคาญ

@annoying_squid: สิ่งที่ OOP ให้ไว้คือความสามารถในการใช้ประเภทของอาร์กิวเมนต์หลักของ funciton เพื่อเลือกเนมสเปซ หากฉันมีitประเภทของตัวแปรการSuperFancyWhizBangเรียกใช้วิธีการอย่างใดอย่างหนึ่งSuperFancyWhizBangในitไม่จำเป็นต้องเขียนออกมาSuperFancyWhizBang; บอกว่าit.woozle()จะนำคอมไพเลอร์ที่จะมองโดยอัตโนมัติภายในwoozle SuperFancyWhizBang
supercat

3

มีวิธีที่จะทำทุกอย่างด้วยเครื่องทัวริงหรืออย่างน้อยก็ในภาษาแอสเซมบลีสำหรับรหัสเครื่องที่โปรแกรม C หรือ C ++ จะคอมไพล์ลงในที่สุด

ดังนั้นความแตกต่างไม่เกี่ยวกับสิ่งที่รหัสสามารถทำได้ แต่เกี่ยวกับสิ่งที่ผู้คนสามารถทำได้

ผู้คนทำผิดพลาด จำนวนมาก

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

ยิ่งโครงการยิ่งมีโอกาสผิดพลาดมากเท่าใด ซึ่ง coder ใหม่อาจไม่ได้รับการสัมผัสหากพบกับโปรแกรมขนาดเล็กเท่านั้น ดังนั้นศักยภาพในการไขปริศนาว่าทำไม OOP จึงมีค่า


2

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


เพียงแค่ใช้ฟังก์ชั่นต้นแบบ นั่นคือการห่อหุ้ม
รำคาญ

2

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

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


1

หลายคนกล่าวว่าโปรแกรมใด ๆ เมื่อรวบรวมแล้วจะกลายเป็นรหัสไบนารี่และเนื่องจากไบนารีสตริงอาจถูกใช้เพื่อเป็นตัวแทนของจำนวนเต็มในที่สุดโปรแกรมใด ๆ ก็เป็นเพียงตัวเลข อย่างไรก็ตามการกำหนดจำนวนที่คุณต้องการนั้นค่อนข้างยากและนั่นคือสาเหตุที่ภาษาโปรแกรมระดับสูงออกมา ภาษาการเขียนโปรแกรมเป็นเพียงรูปแบบของรหัสการประกอบที่พวกเขาผลิตในที่สุด ฉันต้องการอธิบายความแตกต่างระหว่างขั้นตอนการเขียนโปรแกรมและ OO โดยบทความนี้เป็นเรื่องดีมากเกี่ยวกับ Context Oriented Programming http://www.jot.fm/issues/issue_2008_03/article4/

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

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

นี้ช่วยให้ encapsulation และ modularization

ป้อนคำอธิบายรูปภาพที่นี่

รูป -c เป็นเรื่องเกี่ยวกับการเขียนโปรแกรมที่มุ่งเน้นเรื่องการขยายวิธีการจัดส่งวัตถุโดยอีกมิติหนึ่ง

หวังว่าสิ่งนี้จะช่วยให้คุณคิดเกี่ยวกับ OOP จากมุมมองที่ต่างออกไป


0

(+1) การถามคำถามเกี่ยวกับสิ่งที่คุณไม่เข้าใจมันเป็นเรื่องที่ดีแม้ว่ามันจะฟังดูไร้สาระก็ตาม

ความแตกต่างคือการเขียนโปรแกรมเชิงวัตถุและคลาส "Plain C" ทำงานกับข้อมูลและฟังก์ชั่น "C ++" เพิ่มแนวคิด "วัตถุ & คลาส" รวมถึงแนวคิดรองที่เกี่ยวข้องหลายประการ

อย่างไรก็ตามฉันสนับสนุนให้นักพัฒนาเรียนรู้ "Plain C" ก่อน "C ++" หรือ "Pascal ขั้นตอน" ก่อน "Object Pascal"

นักพัฒนาหลายคนคิดว่านักเรียนควรสอนเพียงสิ่งเดียวเท่านั้น

ตัวอย่างเช่นครูเก่าที่ไม่ได้รับ OO และสอนเฉพาะ "Plain Structured C"

หรือครู "hipster" ที่สอนเฉพาะ OO แต่ไม่ใช่ "Plain C" เพราะ "คุณไม่ต้องการ" หรือทั้งสองอย่างโดยไม่สนใจคำสั่งสอน

ฉันคิดว่านักเรียนควรได้รับการสอนทั้ง "Structured Plain C" และ "Object Oriented C (C ++)" ด้วย "Plain C" ก่อนและ "C ++" ในภายหลัง

ในโลกแห่งความจริงคุณต้องเรียนรู้ทั้งกระบวนทัศน์ (รวมถึงกระบวนทัศน์อื่น ๆ เช่น "การทำงาน")

การคิดโปรแกรมที่มีโครงสร้างเป็น "วัตถุ" ขนาดใหญ่ซิงเกิลอาจช่วยได้

คุณควรเน้นในเนมสเปซ ("โมดูล") ทั้งสองภาษาครูจำนวนมากก็ไม่สนใจ แต่สำคัญ


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

การเขียน MODULE_Foo () ทุกที่อาจเป็นภาพที่ยุ่งเหยิง แต่อย่างน้อยคุณก็รู้ว่ามันคือฟังก์ชั่นอะไร
Calmarius

@Calmarius การแก้ปัญหาได้อย่างชัดเจนคือการไม่ตั้งชื่ออะไรfoo

0

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


-1

การเขียนโปรแกรมเชิงวัตถุคือการเขียนโปรแกรมขั้นตอนพร้อมกล่อง

ใน PP คุณมีหนึ่งกล่องหนึ่งรัฐซึ่งมีขนาดใหญ่อย่างไม่น่าเชื่อเมื่อโครงการเติบโตขึ้นทำให้เกิดผลข้างเคียงปรากฏทุกครั้งที่คุณลืมสถานะใหญ่ ๆ

ใน OO คุณมีกล่องจำนวนมากหลายรัฐและเมื่อโครงการเติบโตขึ้นกล่องจะโตขึ้นเล็กน้อยและจำนวนกล่องก็เพิ่มขึ้นเป็นจำนวนมาก

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

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

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

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

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

สิ่งนี้จะเอาชนะ PP ได้มากเพราะคุณสามารถขยายโครงการได้นานขึ้นเนื่องจากไม่มีสถานะ XXXXXXXL อีกต่อไปที่จะติดตาม

โดยสรุป PP น่าจะเป็นวิธีที่ง่ายที่สุดในการเข้าถึงโปรแกรมอย่างง่ายและ FP น่าจะเป็นวิธีที่ง่ายที่สุดในการเข้าใกล้โปรแกรมที่ซับซ้อน

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

และคุณจะได้รับการทดสอบหน่วยที่เชื่อถือได้ 100% ฟรี

และคุณไม่จำเป็นต้องเขียน "ส่วนตัวคงสุดท้ายสุดท้าย of_doom อัจฉริยะอัจฉริยะ string_1"

และคุณได้รับความเท่าเทียมกันฟรี


-3

ความแตกต่างประโยคเดียวอย่างง่ายคือC ++ คือ C กับ Classes (ถึงตอนนี้จะมากขึ้น)ฉันไม่ได้ว่าทำไมคุณไม่ต้องการเรียนรู้ความแตกต่างระหว่างสองโดยการอ่านบทความที่ดีใน C ++ ที่ Wikipedia .... . บทความนี้จะช่วยคุณได้อย่างมาก: - C ++ (Wikipedia)

googling เกี่ยวกับปัญหาจะช่วยให้ การขอให้คนสุ่มอธิบายเรื่องนี้อาจเป็นเรื่องยุ่งยาก IMHO เข้าใจดีกว่าการอ่านมากกว่าการถามใครสักคน


ฉันได้อ่านสิ่งเหล่านี้แล้ว แต่พวกเขาบอกว่าใช้ไปที่ไหน แต่ก็ยังไม่สามารถแก้ไขคำถามของฉันได้
niko

ฉันไม่ได้ถามคำถามโดยไม่ต้องใช้ความพยายามใด ๆ ที่ฉัน googled แต่ก็ยังไม่สามารถเข้าใจความแตกต่างดังนั้นฉันได้พบกับ stackoverflow เพื่อช่วยฉันด้วยสิ่งเหล่านี้
niko

1
@ นิโก้คุณทำให้ฉันผิดที่นี่ สิ่งที่ฉันหมายถึงคือคุณควรพยายามเข้าใจความแตกต่างระหว่างสองสิ่งนี้ด้วยการอ่าน ถามเพื่อนของคุณไม่ดี เพราะพวกเขาจะให้ความเข้าใจของตัวเองซึ่งอาจไม่พอใจคุณ แต่ไม่ต้องกังวลมีเพื่อนที่ดีอยู่ที่นี่พวกเขาจะช่วยคุณอย่างแน่นอน :-)
Pankaj Upadhyay

2
ฉันไม่ได้ลงคะแนน แต่ถูกล่อลวงอย่างมากที่ "C ++ คือ C กับคลาส" พวกเราที่สามารถทำ C ++ ได้จริงพยายามลาออกจากหัวของผู้คน
DeadMG

1
@Pankaj: ถูกต้อง มันคือ C กับคลาส แน่นอนที่สุดคือไม่ใช่ C กับ Classes อีกต่อไปและเรียกมันว่าเกือบ 30 ปีแล้ว C ++ ได้หายไปนานมากตั้งแต่นั้นมา คนที่ใช้รหัส C ++ ไม่เคยเคยอ้างถึงอย่างนั้น มันส่งเสริมนิสัยที่เลวร้ายที่สุดและความประทับใจที่ผิด
DeadMG
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.