动态类型
在groovy中,不指定接口参数类型的时候,默认提供的是Object,在任何类实现它的时候,都可以转换成对应的类型,这被称为鸭子类型。
package groovy
class Man{
void helpMoveThings(){
//......
println "Man's helping"
}
}
class WoMan{
void helpMoveThings(){
//......
println "WoMan's helping"
}
}
class Elephant{
void helpMoveThings(){
//......
println "Elephant's helping"
}
void eatSugarcane(){
//....
println "I' love sugarcanes"
}
}
def takeHelp(helper) {
helper.helpMoveThings()
}
来看一下结果
Man's helping
WoMan's helping
Elephant's helping
沒有指定類型的时候,就可以成为任何类型
多方法
如果类中有重载的方法,Groovy会聪明的选择正确的实现。不仅基于目标对象(调用方法的对象),还基于所提供的的参数,因为方法的分派基于多个实体(目标加参数),所以这被称做多分派或多方法。
先看一个例子:
import java.util.ArrayList;
import java.util.Collection;
public class UsingCillection1 {
public static void main(String [] args){
ArrayList<String> lst=new ArrayList<>();
Collection<String> col=lst;
lst.add("one");
lst.add("two");
lst.add("three");
col.remove(0);
lst.remove(0);
System.out.println("Added three items,removed two,so 1 item to remain");
System.out.println("Number of elements is:"+lst.size());
System.out.println("Number of elements is:"+col.size());
}
}
输出的结果为:
Added three items,removed two,so 1 item to remain
Number of elements is:2
Number of elements is:2
在groovy中,同样的方法:
class UsingCillection1111 {
public static void main(String [] args){
ArrayList<String> lst=new ArrayList<>();
Collection<String> col=lst;
lst.add("one");
lst.add("two");
lst.add("three");
col.remove(0);
lst.remove(0);
System.out.println("Added three items,removed two,so 1 item to remain");
System.out.println("Number of elements is:"+lst.size());
System.out.println("Number of elements is:"+col.size());
}
}
groovy中输出的是:
Added three items,removed two,so 1 item to remain
Number of elements is:1
Number of elements is:1
这就是多方法的好处了。
在java中,lst引用的是一个ArrayList实例,而Collection类型的col引用的java代码,lst引用的是一个ArrayList实例,而Collection类型的col引用的是同一个实例,我们向lst中加入3个元素,然后移除一个,移除操作去掉了列表的第一个元素,现在我们想调用col.remove(0)来移除另外一个元素。然而,collection接口的remove()方法想接收的是一个object,所以java吧0装箱成一个Integer,因为这个Integer实例不是列表中的元素,所以这个方法调用没有移除掉任何东西。
而在groovy中,多方法就很好的处理这个问题。
静态类型检查,
如果使用静态编译检查,不进行运行时注入方法或属性,来加强代码的严谨。
使用@TypeChecked注解,让groovy去检查这些错误,这个注解可以用于单个类或者方法上,如果用于一个类,则全检查,如果在方法上,则只检查这个方法,
还可以使用@TypeChecked(TypeCheckingMode.SKIP)注解,跳过不进行静态类型检查。
静态编译
动态类型的灵活是有代价 的,groovy的执行效率大概要比java低10%,如果不使用多方法和动态类型,放弃元编程,可以使用静态编译,使生成的字节码文件更有效率。
可以使用@CompileStatic注解让Groovy执行静态编译。使生成的字节码文件很像java。