CodeGym /Java Blog /Toto sisi /getter 和 setter
John Squirrels
等級 41
San Francisco

getter 和 setter

在 Toto sisi 群組發布
你好!在前面的章節中,您已經學習瞭如何使用方法和字段聲明您自己的完整類。在今天的課程中,我們將討論 Java 中的 Getters 和 Setters。這是一個重大的進步,幹得好!但現在我不得不告訴你一個不愉快的事實。我們沒有正確聲明我們的類!為什麼?乍一看,下面的類沒有任何錯誤:

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類來表示貓。然後你回家。你不在的時候,另一個程序員來上班了。他創建了自己的Main類,並開始使用您編寫的Cat類。

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
他為什麼這樣做以及它是如何發生的(也許這個人累了或者睡眠不足)並不重要。其他事情很重要:我們當前的Cat類允許為字段分配絕對瘋狂的值。結果,該程序的對象具有無效狀態(例如這只 -1000 歲的貓)。那麼我們在聲明我們的類時犯了什麼錯誤呢?我們公開了班級的數據。姓名、年齡和體重字段是公開的。它們可以在程序的任何地方訪問:只需創建一個Cat對象,任何程序員都可以通過點 ( . ) 運算 符直接訪問其數據

Cat cat = new Cat();
cat.name = "";
這裡我們直接訪問名稱字段並設置它的值。我們需要以某種方式保護我們的數據免受不當的外部干擾。我們需要做什麼?首先,所有實例變量(字段)都必須標有私有修飾符。Private 是 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對象
  • 他們應該能夠從現有對像中讀取數據(例如,獲取現有貓的名稱或年齡)
  • 還應該可以分配字段值。但在這樣做時,應該只允許有效值。我們的對象應該避免無效值(例如 age = -1000 等)。
這是一份不錯的要求清單!實際上,所有這些都可以通過稱為 getter 和 setter 的特殊方法輕鬆實現。
吸氣劑和吸氣劑 - 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。請注意,getter 具有 public 訪問修飾符,即它們可以從程序中的任何地方使用。但是如何分配值呢?這就是 setter 方法的用途

public void setName(String name) {
   this.name = name;
}
如您所見,它們也很簡單。我們在Cat對像上調用setName()方法,傳遞一個字符串作為參數,並將該字符串分配給對象的名稱字段。

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());
   }
}
在這裡,我們同時使用了 getter 和 setter。首先,我們使用一個 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
在 setter 內部,我們創建了一個限制,以防止我們嘗試設置無效數據。Smudge 的年齡沒有改變。您應該始終創建 getter 和 setter。即使對您的字段可以採用的值沒有限制,這些輔助方法也不會造成任何傷害。想像一下以下情況:您和您的同事正在一起編寫程序。您創建一個帶有公共字段的Cat類。所有的程序員都在隨心所欲地使用它們。然後在一個晴朗的日子你意識到:“糟糕,遲早有人可能會不小心給權重分配一個負數!我們需要創建 setter 並將所有字段設為私有!” 你就是這麼做的,並立即破解了你同事編寫的所有代碼。畢竟,他們領域直接。

cat.name = "Behemoth";
現在字段是私有的,編譯器會拋出一堆錯誤!

cat.name = "Behemoth";//error! The Cat class's name field is private!
在這種情況下,最好隱藏字段並從一開始就創建 getter 和 setter。您所有的同事都會使用它們。如果你後來才意識到你需要以某種方式限製字段值,你可以在 setter 中編寫檢查。沒有人的代碼會被破壞。當然,如果你想訪問一個字段只是“只讀”,你可以只為它創建一個 getter。只有方法應該在外部可用(即在您的班級之外)。數據應該被隱藏。我們可以拿手機做個類比。想像一下,你拿到的不是通常的封閉式手機,而是一個外殼打開的手機,裡面有各種突出的電線、電路等。但手機能正常工作:如果你真的很努力地戳電路,你甚至可能能夠打電話。但是你'
吸氣劑和吸氣劑 - 3
相反,製造商為您提供了一個界面:用戶只需輸入正確的數字,按下綠色的通話按鈕,通話就會開始。她不關心電路和電線內部發生了什麼,或者它們是如何完成工作的。在這個例子中,公司限制了對手機“內部”(數據)的訪問,並且隻公開了一個接口(方法)。結果,用戶得到了她想要的東西(打電話的能力),當然不會破壞裡面的任何東西。 為了鞏固您所學的知識,我們建議您觀看我們的 Java 課程中的視頻課程
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION