1. บทนำ

เราต้องการอุทิศบทเรียนของวันนี้ให้กับการห่อหุ้ม คุณรู้อยู่แล้วว่ามันคืออะไรในแง่ทั่วไป

การห่อหุ้ม

ประโยชน์ของการห่อหุ้มคืออะไร? มีค่อนข้างน้อย แต่ฉันสามารถแยกแยะได้สี่รายการในความคิดของฉันคือรายการหลัก:


2. สถานะภายในที่ถูกต้อง

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

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

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

ตัวอย่างเช่น สมมติว่าเราต้องการให้ทุกคนสามารถทราบจำนวนองค์ประกอบในคอลเล็กชันของเรา แต่เราไม่ต้องการให้พวกเขาเปลี่ยนคอลเล็กชันโดยไม่ได้รับอนุญาตจากเรา จากนั้นเราประกาศprivate int countตัวแปรและpublic getCount()เมธอด

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

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


3. ตรวจสอบอาร์กิวเมนต์เมธอด

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

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

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

แต่เมื่อวันที่ 30 มีนาคมมาถึง โปรแกรมจะไม่พบใครเลย เพราะปฏิทินไม่มีวันที่ 32 มีนาคม โปรแกรมมีข้อผิดพลาดน้อยกว่ามากหากเราตรวจสอบข้อมูลที่ส่งผ่านไปยังเมธอด

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


4. ลดข้อผิดพลาดเมื่อเปลี่ยนรหัส

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

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

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


5. เราตัดสินใจว่าวัตถุของเรามีปฏิสัมพันธ์กับวัตถุภายนอกอย่างไร

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

การห่อหุ้ม 2

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

การห่อหุ้มเป็นสิ่งที่น่าสนใจมาก