โค้ดยิม/จาวาบล็อก/สุ่ม/เก็ตเตอร์และเซ็ตเตอร์
John Squirrels
ระดับ
San Francisco

เก็ตเตอร์และเซ็ตเตอร์

เผยแพร่ในกลุ่ม
สวัสดี! ในบทที่แล้ว คุณได้เรียนรู้วิธีประกาศคลาสเต็มรูปแบบของคุณเองด้วยเมธอดและฟิลด์ต่างๆ แล้ว ในบทเรียนวันนี้ เราจะพูดถึง Getters และ Setters ใน Java นี่เป็นความคืบหน้าอย่างจริงจัง ทำได้ดีมาก! แต่ตอนนี้ฉันต้องบอกความจริงที่ไม่พึงประสงค์แก่คุณ เราไม่ได้ประกาศชั้นเรียนของเราอย่างถูกต้อง! ทำไม เมื่อแรกเห็น คลาสต่อไปนี้ไม่มีข้อผิดพลาด:
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!");
   }
}
แต่มันไม่ ลองจินตนาการว่าคุณกำลังนั่งทำงานและเขียน คลาส Cat นี้ เพื่อเป็นตัวแทนของแมว แล้วคุณกลับบ้าน ในขณะที่คุณไม่อยู่ โปรแกรมเมอร์อีกคนมาถึงที่ทำงาน เขาสร้างคลาส หลักของตัวเองซึ่งเขาเริ่มใช้ คลาส Catที่คุณเขียน
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
ไม่สำคัญว่าเขาทำไปทำไมและเกิดขึ้นได้อย่างไร (ผู้ชายอาจจะเหนื่อยหรือนอนไม่พอ) สิ่งอื่นที่สำคัญ: คลาส Cat ปัจจุบันของเรา อนุญาตให้ฟิลด์สามารถกำหนดค่าที่บ้าคลั่งได้ เป็นผลให้โปรแกรมมีวัตถุที่มีสถานะไม่ถูกต้อง (เช่น cat ตัวนี้ที่มีอายุ -1000 ปี) เราทำผิดพลาดอะไรเมื่อประกาศชั้นเรียนของเรา? เราเปิดเผยข้อมูลของชั้นเรียนของเรา ช่องชื่อ อายุ และน้ำหนักเป็นสาธารณะ สามารถเข้าถึงได้จากทุกที่ในโปรแกรม: เพียงสร้าง วัตถุ Catและโปรแกรมเมอร์คนใดก็ตามสามารถเข้าถึงข้อมูลได้โดยตรงผ่านตัวดำเนินการ dot ( . )
Cat cat = new Cat();
cat.name = "";
ที่นี่เรากำลังเข้าถึงฟิลด์ชื่อโดยตรงและตั้งค่า เราจำเป็นต้องปกป้องข้อมูลของเราจากการรบกวนจากภายนอกที่ไม่เหมาะสม เราต้องทำอะไร? ขั้นแรก ตัวแปรอินสแตนซ์ทั้งหมด (ฟิลด์) จะต้องทำเครื่องหมายด้วยตัวดัดแปลงส่วนตัว ส่วนตัวคือตัวแก้ไขการเข้าถึงที่เข้มงวดที่สุดใน Java เมื่อคุณดำเนินการแล้ว ฟิลด์ของ คลาส Catจะไม่สามารถเข้าถึงได้จากภายนอกคลาส
public class Cat {

   private String name;
   private int age;
   private 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!");
   }
}

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";//error! The Cat class's name field is private!
   }
}
คอมไพเลอร์เห็นสิ่งนี้และสร้างข้อผิดพลาดทันที ตอนนี้เขตข้อมูลได้รับการป้องกัน แต่กลายเป็นว่าเราปิดการเข้าถึงซึ่งอาจเข้มงวดเกินไป: คุณไม่สามารถรับน้ำหนักแมวที่มีอยู่ในโปรแกรมได้ แม้ว่าคุณจะจำเป็นก็ตาม นี่ไม่ใช่ตัวเลือก อย่างที่เป็นอยู่ คลาสของเราใช้ไม่ได้โดยพื้นฐานแล้ว ตามหลักการแล้ว เราต้องอนุญาตการเข้าถึงแบบจำกัดบางประเภท:
  • โปรแกรมเมอร์อื่น ๆ ควรสามารถสร้างวัตถุCat ได้
  • พวกเขาควรจะสามารถอ่านข้อมูลจากวัตถุที่มีอยู่ (เช่น รับชื่อหรืออายุของแมวที่มีอยู่)
  • นอกจากนี้ยังควรกำหนดค่าของฟิลด์ได้ด้วย แต่ในการทำเช่นนั้น ควรอนุญาตเฉพาะค่าที่ถูกต้องเท่านั้น วัตถุของเราควรได้รับการปกป้องจากค่าที่ไม่ถูกต้อง (เช่น อายุ = -1000 เป็นต้น)
นั่นเป็นรายการข้อกำหนดที่ดี! ในความเป็นจริง ทั้งหมดนี้ทำได้อย่างง่ายดายด้วยวิธีการพิเศษที่เรียกว่า getters และ setters
เก็ตเตอร์และเซ็ตเตอร์ - 2
ชื่อเหล่านี้มาจาก "get" (เช่น "วิธีการรับค่าของฟิลด์") และ "set" (เช่น "วิธีการตั้งค่าฟิลด์") มาดูกันว่าหน้าตาของพวกมันเป็นอย่างไรในคลาส Cat ของเรา :
public class Cat {

   private String name;
   private int age;
   private 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!");
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       this.age = age;
   }

   public int getWeight() {
       return weight;
   }

   public void setWeight(int weight) {
       this.weight = weight;
   }
}
อย่างที่คุณเห็น พวกมันดูค่อนข้างเรียบง่าย :) ชื่อของพวกมันมักจะประกอบด้วย "get"/"set" บวกกับชื่อของฟิลด์ที่เกี่ยวข้อง ตัวอย่างเช่น เมธอด getWeight()จะส่งคืนค่าของฟิลด์น้ำหนักสำหรับออบเจกต์ที่ถูกเรียกใช้ นี่คือลักษณะที่ปรากฏของโปรแกรม:
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       String smudgeName = smudge.getName();
       int smudgeAge = smudge.getAge();
       int smudgeWeight = smudge.getWeight();

       System.out.println("Cat's name: " + smudgeName);
       System.out.println("Cat's age: " + smudgeAge);
       System.out.println("Cat's weight: " + smudgeWeight);
   }
}
เอาต์พุตคอนโซล:
Cat's name: Smudge
Cat's age: 5
Cat's weight: 4
ตอนนี้คลาสอื่น ( Main ) สามารถเข้าถึง ฟิลด์ Cat ได้ แต่ผ่าน getter เท่านั้น โปรดทราบว่า getters มีตัวแก้ไขการเข้าถึงแบบสาธารณะ นั่นคือสามารถเข้าถึงได้จากทุกที่ในโปรแกรม แต่สิ่งที่เกี่ยวกับการกำหนดค่า? นี่คือวิธีการตั้งค่าสำหรับ
public void setName(String name) {
   this.name = name;
}
อย่างที่คุณเห็น มันเรียบง่ายเช่นกัน เราเรียก เมธอด setName()บน วัตถุ Catส่งผ่านสตริงเป็นอาร์กิวเมนต์ และสตริงถูกกำหนดให้กับฟิลด์ชื่อของวัตถุ
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);

       System.out.println("Cat's original name: " + smudge.getName());
       smudge.setName("Mr. Smudge");
       System.out.println("Cat's new name: " + smudge.getName());
   }
}
ในที่นี้เราใช้ทั้ง getters และ setters ขั้นแรก เราใช้ getter เพื่อรับและแสดงชื่อเดิมของแมว จากนั้น เราใช้ setter เพื่อกำหนดชื่อใหม่ ("Mr. Smudge") จากนั้นเราใช้ getter อีกครั้งเพื่อรับชื่อ (เพื่อตรวจสอบว่ามีการเปลี่ยนแปลงหรือไม่) เอาต์พุตคอนโซล:
Cat's original name: Smudge
Cat's new name: Mr. Smudge
แล้วอะไรคือความแตกต่าง? เรายังคงกำหนดค่าที่ไม่ถูกต้องให้กับฟิลด์ได้ แม้ว่าเราจะมีตัวตั้งค่า:
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       smudge.setAge(-1000);

       System.out.println("Smudge's age: " + smudge.getAge());
   }
}
เอาต์พุตคอนโซล:
Smudge's age: -1000 years
ข้อแตกต่างคือ setter เป็นวิธีการที่สมบูรณ์ และไม่เหมือนกับฟิลด์ตรงที่เมธอดให้คุณเขียนตรรกะการตรวจสอบที่จำเป็นเพื่อป้องกันค่าที่ยอมรับไม่ได้ ตัวอย่างเช่น คุณสามารถป้องกันไม่ให้กำหนดจำนวนลบเป็นอายุได้ง่ายๆ:
public void setAge(int age) {
   if (age >= 0) {
       this.age = age;
   } else {
       System.out.println("Error! Age can't be negative!");
   }
}
และตอนนี้รหัสของเราทำงานได้อย่างถูกต้อง!
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       smudge.setAge(-1000);

       System.out.println("Smudge's age: " + smudge.getAge());
   }
}
เอาต์พุตคอนโซล:
Error! Age can't be negative!
Smudge's age: 5 years
ภายในตัวตั้งค่า เราสร้างข้อจำกัดที่ป้องกันเราจากการพยายามตั้งค่าข้อมูลที่ไม่ถูกต้อง อายุของ Smudge ไม่เปลี่ยนแปลง คุณควรสร้าง getters และ setters เสมอ แม้ว่าจะไม่มีข้อจำกัดเกี่ยวกับค่าที่ฟิลด์ของคุณสามารถใช้ได้ แต่วิธีการช่วยเหลือเหล่านี้จะไม่ก่อให้เกิดอันตราย ลองนึกภาพสถานการณ์ต่อไปนี้: คุณและเพื่อนร่วมงานของคุณกำลังเขียนโปรแกรมด้วยกัน คุณสร้าง คลาส Catด้วยฟิลด์สาธารณะ โปรแกรมเมอร์ทั้งหมดกำลังใช้พวกเขาตามที่พวกเขาต้องการ แล้ววันดีคืนดีคุณก็ตระหนักว่า "แย่จัง ไม่ช้าก็เร็วอาจมีคนกำหนดน้ำหนักเป็นลบโดยไม่ได้ตั้งใจ! เราจำเป็นต้องสร้างตัวตั้งค่าและทำให้ฟิลด์ทั้งหมดเป็นแบบส่วนตัว!" คุณทำอย่างนั้น และทำลายโค้ดทั้งหมดที่เขียนโดยเพื่อนร่วมงานของคุณทันที ท้ายที่สุดพวกเขา 'ทุ่ง แมวโดยตรง.
cat.name = "Behemoth";
และตอนนี้ฟิลด์เป็นส่วนตัวและคอมไพเลอร์แสดงข้อผิดพลาดมากมาย!
cat.name = "Behemoth";//error! The Cat class's name field is private!
ในกรณีนี้ เป็นการดีกว่าที่จะซ่อนฟิลด์และสร้าง getter และ setter ตั้งแต่เริ่มต้น เพื่อนร่วมงานของคุณทุกคนจะใช้มัน และถ้าคุณรู้ตัวช้าว่าจำเป็นต้องจำกัดค่าของฟิลด์ด้วยวิธีใดวิธีหนึ่ง คุณก็สามารถเขียนเช็คไว้ในตัวตั้งค่าได้ และรหัสของไม่มีใครจะถูกทำลาย แน่นอน ถ้าคุณต้องการเข้าถึงฟิลด์แบบ "อ่านอย่างเดียว" คุณสามารถสร้างเฉพาะ getter สำหรับฟิลด์นั้น ควรใช้เมธอดภายนอกเท่านั้น (เช่น นอกชั้นเรียนของคุณ) ข้อมูลควรถูกซ่อนไว้ เราสามารถเปรียบเทียบได้กับโทรศัพท์มือถือ ลองนึกภาพว่าแทนที่จะใช้โทรศัพท์มือถือแบบปิดปกติ คุณได้รับโทรศัพท์ที่มีเคสแบบเปิดซึ่งมีสายไฟ วงจร ฯลฯ ยื่นออกมาทุกประเภท แต่โทรศัพท์ใช้งานได้: หากคุณพยายามอย่างหนักและแหย่วงจร คุณอาจเป็น สามารถโทรออกได้ แต่คุณ'
เก็ตเตอร์และเซ็ตเตอร์ - 3
ผู้ผลิตจะให้อินเทอร์เฟซแก่คุณแทน: ผู้ใช้เพียงป้อนตัวเลขที่ถูกต้อง กดปุ่มโทรสีเขียว และเริ่มการโทร เธอไม่สนใจว่าข้างในจะเกิดอะไรขึ้นกับวงจรและสายไฟ หรือทำงานอย่างไร ในตัวอย่างนี้ บริษัทจำกัดการเข้าถึง "ภายใน" (ข้อมูล) ของโทรศัพท์ และเปิดเผยเฉพาะอินเทอร์เฟซ (วิธีการ) เป็นผลให้ผู้ใช้ได้รับสิ่งที่ต้องการ (ความสามารถในการโทรออก) และแน่นอนว่าจะไม่ทำลายสิ่งใดภายใน เพื่อเสริมสิ่งที่คุณได้เรียนรู้ เราขอแนะนำให้คุณดูบทเรียนวิดีโอจากหลักสูตร Java ของเรา
ความคิดเห็น
  • เป็นที่นิยม
  • ใหม่
  • เก่า
คุณต้องลงชื่อเข้าใช้เพื่อแสดงความคิดเห็น
หน้านี้ยังไม่มีความคิดเห็นใด ๆ