电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

Groovy编程动态改变对象的能力


发布日期:2022/3/11
 

从Groovybeta开始实现动态改变对象的能力变的十分简单

一开始我们有这样一个类

class Person {String name}

该类的实例都是哑巴不能说话作为造物主的我们该完善它们使它们能自我介绍(添加实例方法)

class Person {String name}// 添加自我介绍的行为taClassintroduce << {println Im $name}

现在让我们看看它们到底是否真的能够开口自我介绍了呢

class Person {String name}// 添加自我介绍的行为taClassintroduce << {println Im $name}def person = new Person(name:山风小子)personintroduce()

运行结果

Im 山风小子

嗯~人类改造成功~

但人应该有性别吧嗯~对的加个性别属性sex(添加属性)

class Person {String name}// 添加自我介绍的行为taClassintroduce << {println Im $name}// 添加性别属性默认为男(Male)taClasssex = Maledef person = new Person(name:山风小子)personintroduce()println personsex

运行结果

Im 山风小子

Male

但做男人累啊~为了买房娶妻拼命赚钱做女人算了做变性手术

class Person {String name}// 添加自我介绍的行为taClassintroduce << {println Im $name}// 添加性别属性默认为男(Male)taClasssex = Maledef person = new Person(name:山风小子)personintroduce()println personsex// 做变性手术变为女的(Female)personsex = Femaleprintln personsex

运行结果

Im 山风小子

Male

Female

作为造物主的我们考虑到手术的风险性为了让其他人知道自己现在是个女的在介绍中添加性别说明

class Person {String name}// 添加自我介绍的行为taClassintroduce << {println Im $name}// 添加性别属性默认为男(Male)taClasssex = Male// 修改之前自我介绍行为添加性别说明taClassintroduce << {println Im $name $sex}def person = new Person(name:山风小子)personintroduce()// 做变性手术变为女的(Female)personsex = Femalepersonintroduce()

运行结果

Im 山风小子 Male

Im 山风小子 Female

为了造人方便点搞个工厂方法(添加类方法即静态方法)

class Person {String name}// 添加自我介绍的行为taClassintroduce << {println Im $name}// 添加性别属性默认为男(Male)taClasssex = Male// 修改之前自我介绍行为添加性别说明taClassintroduce << {println Im $name $sex}def person = new Person(name:山风小子)personintroduce()// 做变性手术变为女的(Female)personsex = Femalepersonintroduce()// 工厂方法造人方便点taClassstaticcreatePerson = { name sex >Person p = new Person()pname = namepsex = sexreturn p}def bluesun = PersoncreatePerson(山风小子 Male)bluesunintroduce()

运行结果

Im 山风小子 Male

Im 山风小子 Female

Im 山风小子 Male

为了方便实例化Person添加一个构造方法(添加构造方法)

class Person {String name}// 添加自我介绍的行为taClassintroduce << {println Im $name}// 添加性别属性默认为男(Male)taClasssex = Male// 修改之前自我介绍行为添加性别说明taClassintroduce << {println Im $name $sex}def person = new Person(name:山风小子)personintroduce()// 做变性手术变为女的(Female)personsex = Femalepersonintroduce()// 工厂方法造人方便点taClassstaticcreatePerson = { name sex >Person p = new Person()pname = namepsex = sexreturn p}def bluesun = PersoncreatePerson(山风小子 Male)bluesunintroduce()// 方便实例化Person添加一个构造方法nstructor << { name sex >new Person(name:name sex:sex)}def daniel = new Person(Daniel Male)danielintroduce()

运行结果

Im 山风小子 Male

Im 山风小子 Female

Im 山风小子 Male

Im Daniel Male

最后引用一个官方例子swapCase来展示一下Groovy是如何增强既有类的能力的(演示如何使用delegate注意演示的是final类String)

taClassswapCase = {>def sb = new StringBuffer()// delegate与this类似引用当前正被改造的对象delegateeach {sb << (CharacterisUpperCase(it as char) ? CharactertoLowerCase(it as char) :CharactertoUpperCase(it as char))}sbtoString()}String s = Hello world!println sswapCase()

运行结果

hELLO WORLD!

<<用于添加方法(如果方法已经存在会发生groovylangGroovyRuntimeException异常)=用于添加方法或覆盖既有方法

而从Groovybeta开始Groovy的动态性有了进一步的增强

我们可以通过respondsTo和hasProperty方法来判断是否存在某个方法和某个属性

class Person {String namepublic Person(name) {thisname = name}def introduce() {println Im $name}def introduce(String name) {println She is $name}}def daniel = new Person(Daniel)// 判断实例daniel是否有方法introduce()if (taClassrespondsTo(daniel introduce)) {danielintroduce()}// 判断实例daniel是否有方法introduce(String)if (taClassrespondsTo(daniel introduce String)) {danielintroduce(Annie)}// 判断实例daniel是否有属性nameif (taClasshasProperty(daniel name)) {println danielname}

运行结果

Im Daniel

She is Annie

Daniel

使用methodMissing方法来处理对那些不存在的方法的调用

class Person {String namepublic Person(name) {thisname = name}def introduce() {println Im $name}def introduce(String name) {println She is $name}}thodMissing = { name args >// 动态添加方法taClass$name = { methodArgs >if (helloequals(name))println $methodArgselse {def argList = ArraysasList(methodArgs)println No method $name with ${argList*class}}}delegate$name(args)}def daniel = new Person(Daniel)danielhello(Leona)danielhi(Annie Leona)

运行结果

{Leona}

No method hi with [class javalangString class javalangString]

类似地使用propertyMissing方法来处理对那些不存在的属性的引用

class Person {String namepublic Person(name) {thisname = name}def introduce() {println Im $name}def introduce(String name) {println She is $name}}taClasspropertyMissing = { String name value >// 动态添加属性taClass$name = value}def daniel = new Person(Daniel)danielsex = Maleprintln danielsex

运行结果

Male

上一篇:JBuilder X 初体验

下一篇:在jbuilder和netbeans中打jar包发布程序