
Apache Groovy 中 Getter 和 Setter 的基本指南
作者:Chris Hermansen
Getter 和 Setter 对于检索和修改外部类变量至关重要。Setter 更新变量值,而 Getter 读取变量值。
Java 的常用用户可能对它们很熟悉。如果您不熟悉,那么当我们深入研究 Apache Groovy 时,您需要了解以下内容。(如果您尚未安装 Groovy,请阅读本系列的介绍。)
“get 概念”(以及相关的“set 概念”)在 Java 中以几种不同的方式出现。一个特别的用途是在 JavaBean 的上下文中,为了实现和强制封装。其工作原理如下
- Java 类将字段(也称为属性)定义为仅在该类中已知的内容。
- 如果类想要向使用该类的程序公开该字段的值,那么它会提供一个方法来获取属性的值,称为“getter”
- 如果类想要允许外部世界调整该类的值,那么它会提供一个方法来设置属性的值,称为“setter”
- 通过将存储值的细节与外部世界对该值的访问分离,类可以自由更改值存储的内部实现细节。
这是一个例子。想象一下创建一个表示圆的类。在内部,该类可以存储圆的原点和半径,并提供 getter 来返回原点、半径、直径、面积和周长的值。使用该类的其他程序将不会意识到当前的实现仅存储原点和半径。如果出于某种原因,该类的维护者决定改为存储原点和面积,那么没有任何外部因素会阻碍这种更改。
这是类
1 import java.lang.*;
2 public class Groovy03a {
3 static public void main(String[] args) {
4 var c = new Circle(1.5d,1.7d,15d);
5 System.out.println("c area = " + c.getA());
6 System.out.println("c circumference = " + c.getC());
7 c.setA(100.0d);
8 System.out.println("c area = " + c.getA() + "; radius = " + c.getR());
9 }
10 }
11 class Circle {
12 private double x, y, r;
13 public Circle(double x, double y, double r) {
14 this.x = x;
15 this.y = y;
16 this.r = r;
17 }
18 public double getX() {
19 return this.x;
20 }
21 public double getY() {
22 return this.y;
23 }
24 public double getR() {
25 return this.r;
26 }
27 public double getA() {
28 return Math.PI * this.r * this.r;
29 }
30 public double getC() {
31 return 2.0d * Math.PI * this.r;
32 }
33 public void setX(double x) {
34 this.x = x;
35 }
36 public void setY(double y) {
37 this.y = y;
38 }
39 public void setR(double r) {
40 this.r = r;
41 }
42 public void setA(double a) {
43 this.r = Math.sqrt(a / Math.PI);
44 }
45 public void setC(double c) {
46 this.r = c / 2.0d / Math.PI;
47 }
48 }
第四行显示创建一个圆,圆心位于 (1.5,1.7),半径为 15.0。
在第五到六行中,使用 getA()
和 getC()
getter 方法来查找圆的面积和半径。
在第七行中使用 setA()
setter 方法将圆的面积设置为 100.0。您可以在 42-44 行看到,这是通过从提供的面积计算内部存储的半径来实现的。
使用集成开发环境 (IDE)(如 NetBeans 或 Eclipse)的程序员依靠他们的 IDE 来帮助编写简单的 getter 和 setter。这意味着他们最终只编写复杂的 getter 和 setter(如上面示例中的 getA()
、getC()
、setA()
和 setC()
)。
Groovy 编程语言对此的处理方式略有不同
- 类的字段(或属性)默认是私有的,并且会自动生成默认的 getter 和 setter
- 赋值语句右侧的
c.a
等价于c.getA()
。 - 赋值语句左侧的
c.a
等价于c.putA(
value-on-the-right-hand-side)
。 - “手动创建”的 getter 和 setter 也可以通过点号表示法访问。
这是 Groovy 中一个类似的例子,首先展示了与 Java 的等价性(第四到八行),然后使用了点号表示法(第九到十二行)
1 import java.lang.*;
2 public class Groovy03a {
3 static public void main(String[] args) {
4 def c = new Circle(1.5d,1.7d,15d)
5 println "c area = " + c.getA()
6 println "c circumference = " + c.getC()
7 c.setA(100.0d)
8 println "c area = " + c.getA() + "; radius = " + c.getR()
9 c.x = 2.3d
10 c.y = 1.9d
11 c.a = 225d
12 println "c.x ${c.x} c.y ${c.y} c.r ${c.r} c.a ${c.a} c.c ${c.c}"
13 }
14 }
15 class Circle {
16 double x, y, r;
17 public Circle(double x, double y, double r) {
18 this.x = x;
19 this.y = y;
20 this.r = r;
21 }
22 public double getA() {
23 return Math.PI * this.r * this.r;
24 }
25 public double getC() {
26 return 2.0d * Math.PI * this.r;
27 }
28 public void setA(double a) {
29 this.r = Math.sqrt(a / Math.PI);
30 }
31 public void setC(double c) {
32 this.r = c / 2.0d / Math.PI;
33 }
34 }
请注意,没有为属性 x
、y
和 r
声明 getter 或 setter。运行上面的代码,您会看到
$ groovy Groovy03a.groovy
c area = 706.8583470577034
c circumference = 94.24777960769379
c area = 99.99999999999999; radius = 5.641895835477563
c.x 2.3 c.y 1.9 c.r 8.462843753216344 c.a 224.99999999999997 c.c 53.173615527165474
$
Getter 和 Setter 的另一种应用是在列表、映射等中
1 import java.lang.*;
2 import java.util.ArrayList;
3 import java.util.HashMap;
4 public class Groovy03b {
5 static public void main(String[] args) {
6 var als = new ArrayList<String>();
7 als.add("Fee");
8 als.add("Fie");
9 als.add("Foe");
10 als.add("Fum");
11 System.out.println("als = " + als);
12 System.out.println("als[2] = " + als.get(2));
13 als.set(3, "Foo");
14 System.out.println("als = " + als);
15 }
16 }
要将元素初始放入 ArrayList
,请使用 add() 方法,如第 7-10 行所示。然后您可以使用 get()
和 set()
按列表索引检索或设置值。同样,对于映射,您可以使用 get()
和 set()
按键检索或设置值。
编译并运行上面的代码,您会看到
$ java Groovy03b
als = [Fee, Fie, Foe, Fum]
als[2] = Foe
als = [Fee, Fie, Foe, Foo]
$
Groovy 为列表和映射上的这些操作提供了更简洁的语法支持。以下是一些执行相同操作的 Groovy 代码
1 def als = []
2 als << "Fee"
3 als << "Fie"
4 als << "Foe"
5 als << "Fum"
6 println "als = " + als
7 println "als[2] = " + als[2]
8 als[3] = "Foo"
9 println "als = " + als
请注意,这里您只是在创建一个 Groovy 脚本,因此没有类定义和其他类似的干扰。
在第二到五行中,使用 <<
运算符,该运算符被重载为 add()
。
在第七到八行中,您正在使用下标表示法 [n]
,当它在赋值语句的右侧或左侧时,它分别代替 get()
和 set()
。
映射也可以使用下标表示法,或者它们可以使用点号表示法引用常量键。也就是说,map["a"]
和 map.a
是等价的。
结论
Getter 和 Setter 以各种形式在 Java 和 Groovy 中无处不在,但与 Java 相比,Groovy 中与它们相关的开销要低得多。
这篇文章是关于 Apache Groovy 系列文章的一部分,请继续关注更多内容.
图片由 Jeff Sheldon 在 Unsplash 上提供
1 条评论
评论已关闭。