运算符重载
Groovy 支持运算符重载,和python 一样,重载对应的方法即可实现对应运算符功能。
class Example{
String msg = "default"
Example(String msg){
this.msg = msg
}
Example plus(Example example){
msg += example.msg
return this
}
static void main(String[] args){
Example exampleA = new Example("A")
Example exampleB = new Example("B")
println((exampleA + exampleB).getMsg())
}
}
输出
AB
以上例子中 +
的功能实现方法对应于 plus
,因此重写了该方法,等同于实现了+
的功能实现
?.安全操作
这个和Kotlin一样,使用?.
调用操作,会在对象调用前,检查该对象是否为null,如果为null,则不进行调用操作,如果有返回值,则返回null
使用例子
def getMessage(){
return "Hello!!"
}
static void main(String[] args){
Example example = new Example()
println("getMessage 1 : ${example?.getMessage()}")
example = null
println("getMessage 2 : ${example?.getMessage()}")
}
输出
getMessage 1 : Hello!!
getMessage 2 : null
默认参数
方法默认参数相对于其他语言已经比较熟悉,Groovy同样也支持。 Groovy 默认参数不局限仅能在末尾参数或者连续到末尾参数才能作为默认参数,它可以将中间参数作为默认参数
使用例子
情况1
def getArray(String a, String b = "obj b", String c, String d) {
return [a, b, c, d]
}
static void main(String[] args){
String a
String b
String c
String d
Example example = new Example()
(a, b, c, d) = example.getArray("obj a", "obj c", "obj d")
println("a -> ${a}, b -> ${b}, c -> ${c}, d -> ${d}")
}
输出
a -> obj a, b -> obj b, c -> obj c, d -> obj d
以上方法中,仅有b参数存在默认参数,而调用getArray
方法仅提供三个参数,Groovy对于不满足默认方法签名的函数调用,会优先匹配到没有提供默认参数的参数上,因此这里obj a
、obj c
、obj d
分别对应于 a、c、d 参数,而 b 则使用默认的参数 obj b
情况2
def getArray(String a, String b = "obj b", String c, String d = "obj d") {
return [a, b, c, d]
}
static void main(String[] args){
String a
String b
String c
String d
Example example = new Example()
(a, b, c, d) = example.getArray("obj a", "obj b", "obj c")
println("a -> ${a}, b -> ${b}, c -> ${c}, d -> ${d}")
}
输出
a -> obj a, b -> obj b, c -> obj c, d -> obj d
情况3
def getArray(String a, String b = "obj b", String c = "obj c", String d, String e = "obj e", String f = "obj f", String g){
return [a, b, c, d, e, f, g]
}
static void main(String[] args){
String a
String b
String c
String d
String e
String f
String g
Example example = new Example()
(a, b, c, d, e, f, g) = example.getArray("obj a", "obj d", "obj d", "obj g")
println("a -> ${a}, b -> ${b}, c -> ${c}, d -> ${d}, e -> ${e}, f -> ${f}, g -> ${g}")
}
输出
a -> obj a, b -> obj d, c -> obj c, d -> obj d, e -> obj e, f -> obj f, g -> obj g
以上三个用例可以知道,当方法提供的调用参数不能满足方法所有参数数量时,会优先补足必须参数的参数值,后再对多出来的调用参数,按照已提供默认参数的参数顺序,进行赋值,覆盖默认参数的参数值。
多赋值
多赋值是对数据的"拆包"行为,在接收者们上需要使用()
小括号,对需要“拆包”分别赋值对象进“打包”
多赋值使用举例
交换变量
static void main(String[] args) {
String a = "obj a"
String b = "obj b"
(a, b) = [b, a]
println("a -> ${a}, b -> ${b}")
}
输出
a -> obj b, b -> obj a
方法返回多结果
def getArray() {
return ['element a','element b','element c','element d','element e']
}
static void main(String[] args){
Example example = new Example()
def (a,b,c) = example.getArray()
println("a -> ${a}, b -> ${b}, c -> ${c}")
}
输出
a -> element a, b -> element b, c -> element c
Tip
- 接受者可以与数组对象数量不一致,如果接受者 > 数组对象,则多出的对象将为null,即使之前有对象,也会被重新置为 null;如果接受者 < 数组对象,则只会接收数组前几个对应的对象内容。
- 被“拆包”对象,可以为数组、List
方法调用括号可选
当方法调用时,存在至少一个参数,可以省略括号
set与get
和 Kotlin 一样,Groovy会自动对下面public的属性进行get和set方法的定义
class Example{
String msg = "default"
static void main(String[] args){
Example example = new Example()
println(example.msg)
example.setMsg("set msg")
println(example.msg)
println(example.getMsg())
}
}
输出
default
set msg
set msg
当然,set、get方法也可以被重写
动态类型
特征
特征有点类似于接口的扩张,特征可以进行方法实现,属性定义,并且类可以多继承特征。 特征用 trait 作为关键词,在使用它时,和接口一样使用implements
进行实现,在其他的特征中继承扩展特征时,使用extends
进行继承扩展(基本使用上和接口一样)。
static void main(String[] args){
C c = new C()
println(c.getMsg())
}
interface X{
String getMsg();
}
trait A implements X{
String getMsg(){
return "A"
}
}
trait B implements X{
String getMsg(){
"B"
}
}
static class C implements B,A{
}
输出
A
Tip
- 如果在多继承中存在方法冲突,则后继承的内容会覆盖前面的(包括属性和方法)。
DSL
Groovy允许在方法调用的时候,省略括号