CodeGym/Java 博客/随机的/getter 和 setter
John Squirrels
第 41 级
San Francisco

getter 和 setter

已在 随机的 群组中发布
个会员
你好!在前面的章节中,您已经学习了如何使用方法和字段声明您自己的完整类。在今天的课程中,我们将讨论 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 课程中的视频课程
评论
  • 受欢迎
你必须先登录才能发表评论
此页面还没有任何评论