Groovy探索 as关键字的深入使用

在前面的系列《Groovy Tip 20  "as"关键字的用法》中,我们已经谈到了"as"关键字的一些激动人心的用法。本篇则要接着前篇的内容说下去,继续来展现"as"关键字的一些更为激动人心的用法。

在前一篇中,我们谈到了"as"关键字的一个用法是进行类型转换。最常用的是形如下面的用法:

def list = ['a','b','c']
println list.class
def strs = list as String[]
println strs.class

这就是一个常用的类型转换的代码,从下面的打印结果可以看出,"as"关键字的使用的确使得变量进行了类型转换。

class java.util.ArrayList
class [Ljava.lang.String;

看到了这个用法,我们可能会想,"as"关键字的这个用法是如何实现的?我们如何想把自己设计的两个类之间进行相互转换,该如何实现。

比如说我们有如下的两个类:

class A
{
def x

}

class B
{
def x
}

如果我们已经得到了一个A类的对象,如下:

def a = new A(x:3)

那么我们如何通过下面的语句获取到一个B类的对象呢?

def b = a as B

其实,很简单,我们只需要在A类里实现"asType"方法即可,如下所示:

class A
{
def x

Object asType(Class type)
{
if(type == B) return new B(x:this.x+1)
}
}

这是我们重写过的A类,那么我们现在就可以测试看看我们是否实现了上面所希望的功能:

def a = new A(x:3)
def b = a as B
println b.class.simpleName
println b.x

运行结果为:

B
4

可以看到,的确是实现了我们预想的功能。

除此之外,"as"关键字还有让我们惊奇的发现。比如,我们有如下的一个简单类:

class C
{
def x
def y

public C(x,y)
{
this.x = x
this.y = y
}
}

那么,我们可以这样实例化它的一个实例:

def list = [1,2]
def c = list as C
println c.class.simpleName
println "${c.x},${c.y}"

运行的结果为:

C
1,2

这真是如魔幻一样。

且慢惊叹,再跟着我们看看下面的例子,比如,我们定义了如下的一个接口:

interface D
{
def test_d()
}

我们就可以这样使用"as"关键字:

def map = [test_d:{println 'ok'}]
def d = map as D
println d.class.simpleName
d.test_d()

运行结果为:

$Proxy0
ok

真的是很酷吧!我们可以看到,"as"关键字是Groovy语言中是一个很重要的关键字,它的用法体现了Groovy语言作为一个动态语言的特点,一切都可以在运行期内在做决定,充分的展现了Groovy语言灵活、快捷的特点。

时间: 2024-11-01 01:34:37

Groovy探索 as关键字的深入使用的相关文章

Groovy探索 关于方法名的DSL

Groovy语言最引以为豪的特点就是DSL了,关于DSL的定义以及分类.优点等,就不是本篇所要阐述的了,大家可以上网查,网上有大量的这方便的介绍.Groovy语言是非常便于设计内部DSL了,在这方面,我的Groovy探索系列已经有了很多专题谈到过使用Groovy语言创建内部DSL的一些方面.本篇所要探索的是一个关于Groovy语言DSL的一个非常小的方面.也是非常不起眼的方面:关于方法名的DSL. 说到方法名的DSL,其实我们在Groovy语言中已经有了非常广泛的应用.比如,我们在一开始学习Gr

Groovy探索 自定义Range 二 自定义Range类与Decorate模式

Decorate模式相信大家都比较熟悉了,是一个"BangOfFour"中最常用的模式之一,实现起来也相当的简单.如果有人不熟悉的话,可以看看<Groovy探索之Decorate模式>,那里面有一个本篇要沿用的例子. 这个例子就是咖啡馆里买咖啡的经典例子,咖啡有原味咖啡,还有根据顾客口味不同进行各种添加,比如加冰.加奶和加糖等等.顾客可以选择不加.加一样或加多样,各种加法的咖啡所买的价格也不一样. 这个例子是Decorate模式实现的最经典的例子.我们在这里希望使用自定义R

Groovy探索 自定义Range 三 自定义Range与责任链模式

责任链模式也是我们比较常用的一种模式,我在<Groovy探索之责任链模式>中有个探索.大家也可以在网上搜索,应该有很多这方面的文章. 在这里,我们将使用自定义的Range类来实现责任链模式,使用的例子还是在<Groovy探索之责任链模式>一文中所谈到的"孙悟空大战二郎神"的这个情节.这样,我们可以把这两篇的文字结合起来看,使得我们能够对比这两种开发方式.使得我们能够深入的理解自定义Range类的使用. 在"孙悟空大战二郎神"这个情节里,重点讲

Groovy探索之MOP 十五 方法名的动态性

到目前为止,我们的<Groovy探索之MOP>系列已经谈到了使用ExpandoMetaClass的方方面面,但值得注意的是,我们通过ExpandoMetaClass给一个类在运行期内添加一个方法,不管是普通方法还是静态方法,我们都是添加一个确定方法名的方法.即我们添加一个方法名为A的方法,然后才能使用这个方法A. 然而,方法名的动态性,其实是我们早已接触过的事情,比如在<Groovy探索之invokeMethod方法>里,我们就可以创建形如"sortByXxxxx()&q

Groovy探索之MOP 十三 Interceptor 三(2)

其实,阻止拦截的使用像在<Groovy探索之MOP 十三 Interceptor 三(1)>中的最后一个例子那像的使用并不多,更多的是在使用拦截器的客户那里决定是否使用拦截器.还是上一篇的那个例子: class Hello { def hello(name) { "hello,$name" } } 我们现在明确的把类中所有的方法进行拦截,拦截器如下: class AllInterceptor implements Interceptor{ Object beforeInvo

Groovy探索之MOP 十二 方法的调用顺序

我们知道,除了使用hook来拦截方法以外,我们还可以通过各种方式来实现方法.如,我们可以在类里直接实现方法:我们可以通过ExpandoMetaClass在运行期内添加方法:我们还可以通过ExpandoMetaClass在运行期内单独给一个对象添加方法. 所有的这些直接添加方法的途径,如果存在hook的话,都是要被hook拦截的.所以,我们可以说,系统是优先调用hook的. 而hook的调用顺序,我们在上一篇<Groovy探索之MOP 十一 运行期内覆盖invokeMethod>已经谈到过了.

Groovy探索之MOP 十一 运行期内覆盖invokeMethod

我们很早就会使用Groovy语言的hook,即"invokeMethod"方法和其他的几个方法.我们会在一个类中实现"invokeMethod"方法,用来分派所有的或部分的在运行期内调用的该类实例的方法.这些我们在<Groovy探索之MOP 一 invokeMethod和methodMissing方法>已经详细的谈到过. 现在,我们已经深入的接触到了Groovy语言的MetaClass,更是也到处使用到了ExpandoMetaClass.我们都已经知道,

Groovy探索之MOP 十 Interceptor 二

在本系列的<Groovy探索之MOP 九 Interceptor 一>中,我们已经详细的介绍了一个简单的拦截器类的方方面面,使得我们初步有了拦截器的基础.本篇需要在前面的拦截器类的基础上,进一步用拦截器类来实现我们的AOP编程. 首先,我们在本系列的第一篇中,所拦截的方法都是固定的方法.现在,我们需要把它扩展成由拦截器类的使用者来指定被拦截的方法. 先还是给出需要被拦截的类来: class Foo { def test1() { println 'test1' } def test2() {

Groovy探索之MOP 一 invokeMethod和methodMissing方法

终于要谈到Groovy语言的MOP特性了,我在前面的章节中零星的谈到了它,却始终没有系统的来谈到它.这是因为Groovy语言的MOP特性实在是太灵活了,比如本章节要谈到的"invokeMethod"和"methodMissing"方法,它们的功能有很大的相似之处,而区别却相当的微妙.但是,不管怎么样,Groovy语言的MOP编程都是我们必须掌握的.而这个系列我没有计划多少个部分谈完,跟<Groovy探索之闭包>系列一样,探索一部分说一部分. 本节要谈到的