groovy 面向对象

1. groovy中类,接口等的定义和使用

1.1 类

右键->New->Groovy Class创建一个groovy类,名字是Person。groovy默认所有的类都是public,所以创建完成的class前面没有public进行修饰。

/**
 * 1.groovy中默认都是public
 * 2.所有的groovy类都默认集成了一个GroovyObject类
 * 这是groovy和java中类的区别
 */
class Person {

    String name

    Integer age

    def increaseAge(Integer years) {
        this.name += years
    }
}

新建一个脚本groovy script,在脚本里面进行Person的使用。

def person = new Person(name: 'android', age: 26)
println "this name is ${person.name}, " +
        "thi age is ${person.age}"

输出结果:

this name is android, thi age is 26

在groovy中直接通过.操作符操作的并不是对象的属性,实际上是调用getName()和getAge()方法。无论是直接通过.还是get/set,最终调用的都是get/set方法,这是和java不同的地方。
调用方法形式如下:

person.increaseAge(10)

1.2 接口

右键->New->Groovy Class,类型是Interface,创建一个Interface类型的class。groovy接口和java最大的不同是groovy不允许定义非public类型的方法。
Action.groovy

/**
 * 接口不允许定义非public类型的额接口
 */
interface Action {
    void eat()

    void drink()

    void play()
}

Person.groovy

/**
 * 1.groovy中默认都是public
 * 2.所有的groovy类都默认集成了一个GroovyObject类
 * 这是groovy和java中类的区别
 */
class Person implements Action{

    String name

    Integer age

    def increaseAge(Integer years) {
        this.name += years
    }

    @Override
    void eat() {

    }

    @Override
    void drink() {

    }

    @Override
    void play() {

    }
}

groovy接口除了不定定义非public类型的方法外,其他和java接口使用几乎一样。 

1.3 Trait

trait和interface类似,不同之处在于trait可以为方法提供默认的实现,如果不提供默认实现,需要为方法添加abstract关键字修饰。
DefaultAction.groovy:

trait DefaultAction {
    abstract void eat()
    void play() {
        println 'I can play'
    }
}

Peroson.groovy

class Person implements DefaultAction{

    String name

    Integer age

    def increaseAge(Integer years) {
        this.name += years
    }

    @Override
    void eat() {

    }
}

使用Person对象:

def person = new Person(name: 'android', age: 26)
person.play()

输出结果:

this name is android, thi age is 26
I can play

2. groovy中的元编程

所谓元编程,是指编写的代码所执行的时机。
无论在java还是groovy,都会调用其他类的方法。当调用一个类的方法时,编译器会判断类中是否存在这个方法,如果存在就直接调用类中的方法。在java中找不到类方法会直接报错,但是groovy即使类中没有对应的方法,编译也是可以通过的,groovy编译器会尝试从MetaClass查找是否有此方法。如果MetaClass中包含了此方法,就会调用MetaClass中的方法。如果MetaClass也没有对应的方法,groovy编译器会继续判断是否重写了methodMissing()方法,如果重写了,就调用methodMissing()方法。如果没有重写会继续判断是否重写了invokeMethod()方法,如果重写了invokeMethod()方法,就调用该方法,否则抛出MissingMethodException异常,这是一个运行时的异常。可以用下面一幅图进行概括,同样也适用于属性调用。


 
2.1 基本流程验证

person.groovy

class Person {

    String name

    Integer age

    def increaseAge(Integer years) {
        this.name += years
    }

    def invokeMethod(String name, Object args) {
        return "the methos is ${name}, the params is ${args}"
    }

    def methodMissing(String name, Object args){
        return "the methos is ${name} is missing"
    }
}

使用person:

def person = new Person(name: 'android', age: 26)
println person.cry()

当没有invokeMethod()和methodMissing()方法时,运行会报出MissingMethodException,当重写了上述2个方法之后,则会按照先后书序调用对应的方法。

2.2 为类动态添加属性

metaClass可以为一个类动态添加属性和方法。

// 为类动态添加一个属性
Person.metaClass.sex = 'male'
def person = new Person(name: 'android', age: 26)
println person.sex
person.sex = 'female'
println "the new sex is: " + person.sex

输出结果:

male
the new sex is: female

2.3 为类动态添加方法

Person.metaClass.sex = 'male'
Person.metaClass.sexUpperCase = { -> sex.toUpperCase()}
def person = new Person(name: 'android', age: 26)
println person.sexUpperCase()

输出结果:

MALE


2.4 为类添加静态方法

Person.metaClass.static.createPerson = {String name, int age ->
    new Person(name: name, age: age)
}
def person3 = Person.createPerson("androidtest", 30)
println person3.name + " and " + person3.age

输出结果:

androidtest and 30

2.5 实现全局有效的功能

上面的实现只是针对本模块内有效,模块外部并不会生效,如果想实现全局有效的功能,需要使用调用ExpandoMetaClass.enableGlobally(),让其全局生效。
代码如下:
Person.groovy:

package expand

class Person {

    String name

    Integer age

    def increaseAge(Integer years) {
        this.name += years
    }

    def invokeMethod(String name, Object args) {
        return "the methos is ${name}, the params is ${args}"
    }

    def methodMissing(String name, Object args){
        return "the methos is ${name} is missing"
    }
}

ApplicationManager.groovy

package expand

/**
 * 模拟应用管理类
 */
class ApplicationManager {

    static void init() {
        ExpandoMetaClass.enableGlobally()
        // 为第三方类添加方法
        Person.metaClass.static.createPerson = {String name, int age ->
            new Person(name: name, age: age)
        }
    }

}

PersonManager.groovy

package expand

/**
 * Person管理类
 */
class PersonManager {
    static Person createPerson(String name, int age) {
        return Person.createPerson(name, age)
    }
}

Entry.groovy

package expand

class Entry {

    static void main(def args) {
        println '应用程序正在启动...'
        //初始化
        ApplicationManager.init()
        println '应用程序初始化完成...'

        def person = PersonManager.
                createPerson('renzhiqiang', 26)
        println "the person name is ${person.name} " +
                "and the age is ${person.age}"
    }
}

运行Entry中的main方法,输出结果:

应用程序正在启动...
应用程序初始化完成...
the person name is renzhiqiang and the age is 26

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值