groovy简明教程(六)面向对象

8. groovy的面向对象

groovy来自java,当然是含有面向对象的基因。

8.1 属性和本地变量

groovy有private,protected,public等访问修饰符,但据groovy 2.0.7测试的结果,这些修饰符都是没有起作用,都是public的访问权限,这似乎是一个bug,但是尚未修复,http://jira.codehaus.org/browse/GROOVY-1875

另外groovy bean会生成getter/setter,当然你也可以覆盖set,可以通过点操作符来调用,也可以通过['propertyName']动态的来访问。

package org.jamee.hello.groovy.bean

class BeanAccessor {
	def dftField;
	private priField;
	protected protField;
	def AnotherBean ab;
}

package org.jamee.hello.groovy.bean

class AnotherBean {
	def name;

	void setName(def name) {
		this.name = 'in setName ' + name;
	}
}

package org.jamee.hello.groovy.main

import org.jamee.hello.groovy.bean.AnotherBean;
import org.jamee.hello.groovy.bean.BeanAccessor;

class GroovyTester {
	static main(args) {
		def ba = new BeanAccessor()
		ba.dftField = 'default value'
		ba.priField = 'private value'
		println ba.dftField
		println ba['dftField']
		println ba.priField
		ba.ab = new AnotherBean()
		ba.ab.name = 'ab\'s name'
		println ba.ab.name;
		ba.protField = 'protected value'
		println ba['protField']
	}
}

 输出:

写道
default value
default value
private value
in setName ab's name
protected value

 

8.2 默认参数,变长参数和命名参数

groovy借用了其他脚本语言的特性,支持默认参数和命名参数,虽然看起来不是那么友好。

 

class Greety {
    def sayHello(person, message="good day") {
        return "Hi, $person, $message"
    }
    def sayHellos(message, person, Object[] persons) { // like def SayHellos(message, person, ...otherPersons)
        return persons.inject(message +" $person,") {words, i -> words += " $i,"}
    }
    def sayHello(Map namedParams) {
        return "${namedParams.message}, ${namedParams.person}"
    }
}

def greety = new Greety()
println greety.sayHello('jhone') // output: Hi, jhone, good day
println greety.sayHello('allen', 'how are you') // output: Hi, allen, how are you
println greety.sayHellos('good day', 'bill', 'clark', 'danny') // called like var args, output:good day bill, clark, danny,
println greety.sayHello(message:'good day', person:'eval') // output:  good day, eval

 8.3 方法调用

groovy的调用方法可以用字符串或字符串变量的方式,即更加方便的使用java的反射。
另外也对令人头疼的NullPointerException提供了更方便的检查方式。
class Foo {
    def callme() {
        return 'foo called'
    }
}

def foo = new Foo()
println foo.callme() // output: foo called
println foo.'callme'() // output: foo called
def mn = 'callme'
println foo."$mn"() // output: foo called

def map = [a:[b:[c:1]]]

println map.a.b.c
// println map.a.x.c // NPE throw
println map?.a?.x?.c // protected

 8.4 构造器

groovy提供了三种构造实例的方式:java传统的方式,as转换构造,和隐式构造。
另外groovy还为构造函数提供了命名参数,这样对于属性很多的类,使用就很方便了,还记得java的builder模式吧,groovy天生支持了。
class Name {
    def firstName;
    def lastName;

    Name(firstName, lastName) {
        this.firstName = firstName
        this.lastName = lastName
    }

    def String toString() {
        return this.firstName + ' ' + this.lastName
    }
}

def n0 = new Name('alex', 'bell')
def n1 = ['bob','jons'] as Name
assert n1 instanceof Name
Name n2 = ['clark', 'lee']
assert n2 instanceof Name

class Person {
    Name name
    def age
    def gender
    def email
}

new Person()
p1 = new Person(name : n0)
println p1.name // output: alex bell
p2 = new Person(name : n1, email : 'bob@gmail.com')
println p2.email // output: bob@gmail.com

8.5 类,包

之前提到过,groovy是java的另一种表现形式,任何一个groovy的脚本都是编译成类的,如果一个脚本不含class,groovy会默认将整个脚本编译成一个类,并加入main方法。
groovy的包的组织形式和java一样,但groovy提供了一个我期待很久的特性,可以给一个类引用一个别名,类似于C中的typedef,这样在一个class中引用两个同名的class就不必要写很长的包名了。
import com.company.util.StringUtil
import com.myCompany.util.StringUtil as MyStringUtil

8.6 GPath,Spread,Use

GPath

可以让你用属性访问短方法调用使得你的代码更加紧凑,例如:

invoices.items.grep{ it.total() > 7000 }.product.name
 对应的Java代码:
private static List getProductNamesWithItemTotal(Invoice[] 
invoices) { 
	List result = new LinkedList(); 
	for (int i = 0; i < invoices.length; i++) { 
		List items = invoices[i].getItems(); 
		for (Iterator iter = items.iterator(); iter.hasNext();) { 
			LineItem lineItem = (LineItem) iter.next(); 
			if (lineItem.total() > 7000){ 
				result.add(lineItem.getProduct().getName()); 
			} 
		} 
	} 
	return result; 
}

Spread操作符(*)

可以将你的集合展开,以方便调用,python也提供了类似的操作。
list = [1,2,3]
range = 1..3

def connect(x, y, z) {
    return x + y + z
}

assert 6 == connect(*list)
assert 6 == connect(*range)

Use操作符

class StringCaculationCategory {
    static String plus(String first, String second) {
        Integer.parseInt(first) + Integer.parseInt(second)
    }
}

use(StringCaculationCategory) {
    println '1' + '2'
}
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值