3.2 getter和setter
Android游戏开发详解
构造方法允许你在创建对象的时候初始化对象的实例变量,但是,它对于随后访问或修改这些值就帮不上什么忙了。此外,由于使用了private修饰符来隐藏变量,我们没有办法来直接完成这两项任务。实际上,如下所示的代码将会导致错误。
...
// somewhere inside the World class...
Coder c3 = new Coder(“Mark”, 30);
String c3Name = c3.name; // cannot reference private variable from another class
c3.age = 25; // cannot modify private variable from another class
...
怎样才能绕开这些限制呢?我们可以将Coder类的实例变量标记为public的,但是,由于第2章所介绍的原因,我们不想这么做。相反,可以在Coder类中创建访问器(accessor)方法。我们将讨论两种类型的访问器方法。
1. getter方法返回了所请求的隐藏变量的值的一个副本(但是,保留该隐藏变量不动)。通过这么做,我们可以使得隐藏变量避免未经授权的修改,同时还允许访问该变量的值。
2. setter方法允许其他的类修改一个隐藏变量的值,只要这些类遵守我们在该setter方法中描述的规则。
我们来看看这些访问器方法的应用。向Coder类添加如下所示的getter和setter方法:getAge()、 setAge()、getName()和setName()(参见程序清单3.6的第26行到第28行)。
程序清单3.6 向Coder.java添加getter和setter方法
01 public class Coder {
02
03 private String name;
04 private int age;
05
06 public Coder(String name, int age) {
07 this.name = name;
08 this.age = age;
09 }
10
11 public void writeCode() {
12 System.out.println(name + " is coding!");
13 }
14
15 public void describe() {
16 System.out.println("I am a coder");
17 System.out.println("My name is " + name);
18 System.out.println("I am " + age + " years old");
19 }
20
21 public String getName() {
22 return name;
23 }
24
25 public int getAge() {
26 return age;
27 }
28
29 public void setName(String newName) {
30 if (newName != null) {
31 name = newName;
32 } else {
33 System.out.println("Invalid name provided!");
34 }
35 }
36
37 public void setAge(int newAge) {
38 if (newAge > 0) {
39 age = newAge;
40 } else {
41 System.out.println("Invalid age provided");
42 }
43 }
44 }
我们的两个getter方法返回了该方法的调用者的name和age变量。这意味着,能够访问(或引用)Coder对象的任何类,都可以调用其getter方法,并且看到Coder的实例变量的值。这里,值是关键字。我们并没有允许访问实例变量最初的版本,而是允许访问存储在其中的值。
两个setter方法允许其他的类修改Coder对象的实例变量,但是,我们可以提供一组规则,以确保这些实例变量不会被非法或无效地修改。在程序清单3.6中,我们的setters拒绝了非正值的age值和null的name值。
让我们在World类中调用getters和setters以测试它们,如程序清单3.7的第8行和第9行所示。
程序清单3.7 在World.java中调用getters和setters
01 public class World {
02 public static void main(String[] args) {
03
04 Coder c = new Coder("Bill", 59);
05 c.describe();
06 System.out.println(""); // empty line for readability
07
08 String cName = c.getName();
09 int cAge = c.getAge();
10
11 System.out.println(cName + ", " + cAge);
12 System.out.println(""); // empty line for readability
13 c.setName("Steve");
14 c.setAge(-5); // This will be rejected by our setter method
15
16 c.describe();
17 }
18
19 }
输出如下所示的结果。
I am a coder
My name is Bill
I am 59 years old
Bill, 59
I am a coder
My name is Steve
Invalid age provided
在前面的例子中,我们能够创建一种方法,来保持Coder对象的实例变量私有,同时允许外界通过公有的访问器方法,来获取(get)和修改(set)这些隐藏的变量。这允许我们保持安全地获取和使用私有变量,同时允许我们访问和修改需要的值。注意,我们的setter方法可以拒绝不合法的参数,因此,我们能够防止World类将Coder对象的年龄修改为−5。