สวัสดี! ขออุทิศบทเรียนของวันนี้ให้กับการ ห่อหุ้มและเริ่มต้นด้วยตัวอย่างทันที :) หลักการห่อหุ้ม - 1ที่นี่คุณมีเครื่องทำโซดาธรรมดา ฉันมีคำถามหนึ่งข้อสำหรับคุณ: มันทำงานอย่างไร พยายามให้คำตอบโดยละเอียด: ถ้วยมาจากไหน รักษาอุณหภูมิภายในอย่างไร เก็บน้ำแข็งไว้ที่ไหน เครื่องรู้ได้อย่างไรว่าต้องเติมน้ำเชื่อมชนิดใด ฯลฯ คุณอาจไม่มีคำตอบสำหรับคำถามเหล่านี้ ยุติธรรมพอเพราะไม่ใช่ทุกคนที่ใช้เครื่องดังกล่าว พวกเขาไม่เป็นที่นิยมในปัจจุบัน ลองยกตัวอย่างอื่น สิ่งที่คุณแน่นอนใช้หลายครั้งทุกวัน โอ้นี่เป็นความคิด! หลักการห่อหุ้ม - 2บอกเราว่าเครื่องมือค้นหาของ Google เป็นอย่างไรทำงาน มันค้นหาข้อมูลที่เกี่ยวข้องกับคำที่คุณป้อนได้อย่างไร? เหตุใดผลลัพธ์บางรายการจึงอยู่ในอันดับสูง และบางรายการไม่ได้อันดับ แม้ว่าคุณจะใช้ Google ทุกวัน แต่โอกาสที่คุณไม่รู้ แต่มันไม่สำคัญ คุณไม่จำเป็นต้องรู้เรื่องนี้ คุณสามารถป้อนข้อความค้นหาในเครื่องมือค้นหาโดยไม่ต้องคำนึงถึงวิธีการทำงาน คุณสามารถซื้อโซดาจากเครื่องโดยไม่รู้ว่ามันทำงานอย่างไร คุณสามารถขับรถได้โดยไม่ต้องเข้าใจว่าเครื่องยนต์สันดาปภายในทำงานอย่างไร และไม่รู้ฟิสิกส์เลย แม้แต่ในระดับประถมศึกษา ทั้งหมดนี้เกิดขึ้นได้ด้วยหนึ่งในหลักการสำคัญของการเขียนโปรแกรมเชิงวัตถุ: การห่อหุ้ม. การ อ่านบทความต่างๆ เกี่ยวกับการเขียนโปรแกรมเชิงวัตถุ (OOP) คุณต้องเคยพบกับข้อเท็จจริงที่ว่าการเขียนโปรแกรมเกี่ยวข้องกับสองแนวคิดทั่วไป: การห่อหุ้มและการซ่อน และผู้เขียนใช้คำว่า "encapsulation" เพื่อหมายถึงสิ่งหนึ่งและอีกสิ่งหนึ่ง เราจะสำรวจคำศัพท์ทั้งสองเพื่อให้คุณเข้าใจอย่างถ่องแท้ ในการเขียนโปรแกรม ความหมายดั้งเดิมของการห่อหุ้มคือการรวมกลุ่มของข้อมูล พร้อมด้วยวิธีการที่ดำเนินการกับข้อมูลนั้น ให้เป็นหน่วยเดียว (เช่น "แคปซูล") ใน Java คลาสคือหน่วยของการห่อหุ้ม คลาสมีทั้งข้อมูล (ฟิลด์) และวิธีการทำงานกับข้อมูลนี้หลักการห่อหุ้ม - 3นี่อาจดูเหมือนเป็นแนวทางที่ถูกต้องสำหรับคุณ แต่ในกระบวนทัศน์การเขียนโปรแกรมอื่นๆ ทุกอย่างถูกจัดเรียงแตกต่างกัน ตัวอย่างเช่น ในการเขียนโปรแกรมเชิงฟังก์ชัน ข้อมูลจะถูกแยกออกจากการดำเนินการอย่างเคร่งครัด ใน OOP โปรแกรมประกอบด้วยแคปซูลหรือคลาสซึ่งประกอบด้วยทั้งข้อมูลและฟังก์ชันสำหรับการทำงานกับข้อมูลนั้น ตอนนี้เรามาพูดถึงการซ่อนตัวกัน เราใช้อุปกรณ์ที่ซับซ้อนทุกประเภทโดยไม่เข้าใจวิธีการจัดระเบียบหรือวิธีการทำงานได้อย่างไร ง่ายมาก: ผู้สร้างของพวกเขาให้อินเทอร์เฟซ ที่ง่ายและสะดวกแก่เรา. บนเครื่องทำโซดา อินเทอร์เฟซคือปุ่มต่างๆ บนแผงควบคุม กดปุ่มเดียว คุณเลือกขนาดถ้วย กดปุ่มอื่นเพื่อเลือกรสชาติ หนึ่งในสามมีหน้าที่เติมน้ำแข็ง และนั่นคือทั้งหมดที่คุณต้องทำ องค์กรภายในของเครื่องไม่สำคัญ สิ่งที่สำคัญคือ มันได้รับ การออกแบบในลักษณะที่ผู้ใช้ต้องกดปุ่มสามปุ่มเพื่อรับโซดา เช่นเดียวกับรถยนต์ ไม่สำคัญว่าเกิดอะไรขึ้นข้างใน สิ่งสำคัญคือเมื่อคุณเหยียบแป้นขวา รถจะเคลื่อนที่ไปข้างหน้า และเมื่อคุณเหยียบแป้นซ้าย รถจะช้าลง. นั่นคือสิ่งที่ซ่อนอยู่ "ภายใน" ทั้งหมดของโปรแกรมถูกซ่อนจากผู้ใช้ สำหรับผู้ใช้ ข้อมูลที่ฟุ่มเฟือยและไม่จำเป็นนี้ ผู้ใช้ต้องการผลลัพธ์สุดท้าย ไม่ใช่กระบวนการภายใน ลองดูที่Autoชั้นเรียนเป็นตัวอย่าง:

public class Auto {

   public void go() {

       /* Some complicated things happen inside the car.
       As a result, it moves forward */
   }

   public void brake() {

       /* Some complicated things happen inside the car.
       As a result, it slows down. */
   }

   public static void main(String[] args) {

       Auto auto = new Auto();

       // From the user's perspective,

       // one pedal is pressed and the car accelerates.
       auto.gas();
      
       // The other is pressed, and the car slows down.
       auto.brake();
   }
}
นี่คือลักษณะของการซ่อนการใช้งานในโปรแกรม Java มันเหมือนกับในชีวิตจริง: ผู้ใช้จะได้รับอินเทอร์เฟซ (วิธีการ) หากผู้ใช้ต้องการรถยนต์ในโปรแกรมเพื่อดำเนินการ เขาหรือเธอเพียงแค่เรียกวิธีการที่ต้องการ สิ่งที่เกิดขึ้นภายในวิธีการเหล่านี้เป็นสิ่งที่ไม่จำเป็น สิ่งที่สำคัญคือทุกอย่างทำงานได้ตามที่ควร เรากำลังพูดถึงการซ่อนการใช้งาน นอกจากนั้น Java ยังมีการซ่อนข้อมูล เราเขียนเกี่ยวกับเรื่องนี้ในบทเรียนเกี่ยวกับ getters และ settersแต่การทบทวนแนวคิดนี้จะไม่เสียหาย ตัวอย่างเช่น เรามีCatคลาส:

public class Cat {

   public String name;
   public int age;
   public int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }

  
}
บางทีคุณจำปัญหาของชั้นเรียนนี้จากบทเรียนที่แล้วได้ไหม ถ้าไม่จำตอนนี้ ปัญหาคือข้อมูล (ฟิลด์) เปิดให้ทุกคน — โปรแกรมเมอร์คนอื่นสามารถสร้างแมวนิรนามที่มีน้ำหนัก 0 และอายุ -1,000 ปีได้อย่างง่ายดาย:

public static void main(String[] args) {

   Cat cat = new Cat();
   cat.name = "";
   cat.age = -1000;
   cat.weight = 0;

}
บางทีคุณสามารถจับตาดูได้ว่าเพื่อนร่วมงานคนใดคนหนึ่งของคุณสร้างวัตถุที่มีสถานะไม่ถูกต้องหรือไม่ แต่จะเป็นการดีกว่ามากที่จะยกเว้นแม้กระทั่งความเป็นไปได้ในการสร้าง "วัตถุที่ไม่ถูกต้อง" ดังกล่าว หลักการห่อหุ้ม - 4กลไกต่อไปนี้ช่วยให้เราบรรลุการซ่อนข้อมูล:
  1. ตัวดัดแปลงการเข้าถึง ( ส่วนตัว , ป้องกัน , แพ็คเกจเริ่มต้น )
  2. ผู้รับและผู้ตั้งค่า
ตัวอย่างเช่น เราสามารถทำเครื่องหมายที่นั่นเพื่อดูว่ามีคนพยายามกำหนดอายุแมวเป็นจำนวนลบหรือไม่ ดังที่เราได้กล่าวไว้ก่อนหน้านี้ ผู้เขียนบทความต่างๆ เกี่ยวกับการห่อหุ้มบางครั้งหมายถึงการรวมข้อมูลและวิธีการ หรือการซ่อน หรือทั้งสองอย่าง (การรวมและการซ่อน) Java มีกลไกทั้งสอง (ไม่จำเป็นต้องเป็นจริงสำหรับภาษา OOP อื่น ๆ ) ดังนั้นความหมายสุดท้ายจึงถูกต้องที่สุด การห่อหุ้มทำให้เรามีข้อได้เปรียบที่สำคัญหลายประการ:
  1. ควบคุมสถานะที่ถูกต้องของวัตถุ มีตัวอย่างข้างต้นนี้ ตัวตั้งค่าและตัวดัดแปลงส่วนตัวทำให้มั่นใจได้ว่าโปรแกรมของเราจะไม่มีแมวที่มีน้ำหนักเป็น 0

  2. ใช้งานง่ายผ่านอินเทอร์เฟซ เหลือแต่วิธีการ "เปิดเผย" ต่อโลกภายนอกเท่านั้น วิธีการโทรก็เพียงพอแล้วที่จะได้ผล — ไม่จำเป็นต้องลงลึกในรายละเอียดว่าทำงานอย่างไร

  3. การเปลี่ยนแปลงรหัสไม่ส่งผลกระทบต่อผู้ใช้ เราทำการเปลี่ยนแปลงใด ๆ และทั้งหมดภายในวิธีการ สิ่งนี้ไม่ส่งผลกระทบต่อผู้ใช้เมธอด: หากรหัสที่ถูกต้องก่อนหน้านี้คือ "auto.gas()" เพื่อใช้คันเร่ง ก็จะยังคงเป็นต่อไป ข้อเท็จจริงที่ว่าเราเปลี่ยนแปลงบางอย่างในเมธอด gas() ยังคงมองไม่เห็นสำหรับผู้ใช้: เช่นเดิม ผู้โทรก็ได้รับผลลัพธ์ที่ต้องการ