Gradle 自我學(xué)習(xí)四-Groovy 語(yǔ)法之面向?qū)ο?/h1>

Groovy面向?qū)ο?/h1>

一、groovy中類腹尖,接口等的定義和使用

  • 類的定義與使用
//在idea中直接新建一個(gè)Groovy Class

/**
 * groovy中默認(rèn)都是public狮荔,groovy類最終都會(huì)繼承GroovyObject
 */
class Person {
    //默認(rèn)生成get/set方法
    String name
    Integer age

    //方法也默認(rèn)是public的,def表明方法的返回類型是Object的
    def increaseAge(Integer years) {
        this.age += years
    }
}


//在腳本文件中使用定義好的類

//沒(méi)有定義構(gòu)造方法贫贝,也可以在創(chuàng)建對(duì)象是傳入初始值秉犹,可傳可不傳
def person = new Person(name: 'groovy', age: 6)
println "the name is $person.name,the age is $person.age"  //the name is groovy,the age is 6

person.increaseAge(5)

//無(wú)論使用.還是get/set最終都會(huì)調(diào)用get/set方法
println person.age //11
  • 接口的定義與使用
/**
 * groovy中接口不允許定義非public類型的方法
 */
interface Action {
    void eat()

    void work()

    void sleep()
}


//與java中一致
class Person implements Action{
    //默認(rèn)生成get/set方法
    String name
    Integer age

    //方法也默認(rèn)是public的,def表明方法的返回類型是Object的
    def increaseAge(Integer years) {
        this.age += years
    }

    @Override
    void eat() {}

    @Override
    void work() {}

    @Override
    void sleep() {}
}
  • Trait的定義與使用
//Trait 和接口幾乎一模一樣稚晚,只不過(guò)trait可以給接口提供默認(rèn)的實(shí)現(xiàn)崇堵,
//相當(dāng)于java中接口的適配器模式,直接繼承接口就需要實(shí)現(xiàn)該接口的所有方法客燕,但是很多時(shí)候我們里面有很多方法使我們不需要的鸳劳,這個(gè)時(shí)候就可以定義一個(gè)適配器實(shí)現(xiàn)這個(gè)接口,給我們不需要的方法提供一個(gè)默認(rèn)實(shí)現(xiàn)也搓,這樣我們就可以只關(guān)注我們需要的方法了

trait DefaultAction {
    abstract void eat()

    void work() {
        println 'i can work'
    }

    abstract void sleep()
}

class Person2 implements DefaultAction {

    @Override
    void eat() {}

    @Override
    void sleep() {}
}

def person2 = new Person2()
person2.work() //i can work

二赏廓、 groovy中的元編程

  • 什么是元編程?
    簡(jiǎn)單的理解就是編寫代碼執(zhí)行的時(shí)期涵紊,比如由編譯執(zhí)行的java,運(yùn)行時(shí)執(zhí)行的代碼(java反射)
  • groovy中運(yùn)行時(shí)執(zhí)行時(shí)序圖


    image.png
class Person1 {
    def invokeMethod(String name, Object args) {
        return "the method is $name,the params is $args"
    }
}

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


class Person3 {

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

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

Person1 person1 = new Person1()
Person2 person2 = new Person2()
Person3 person3 = new Person3()

println person1.cry() //the method is cry,the params is []
println person2.cry() //the method cry is missing
println person3.cry() //the method cry is missing

//可以看到符合運(yùn)行時(shí)時(shí)序圖,當(dāng)調(diào)用一個(gè)類中不存在的方法時(shí),若重寫了invokeMethod方法或者methodMissing方法時(shí)幔摸,會(huì)調(diào)用該方法(methodMissing的優(yōu)先級(jí)更高)
  • MetaClass
    前面的示例說(shuō)明了groovy的運(yùn)行時(shí)執(zhí)行時(shí)序摸柄,那么當(dāng)中的MetaClass又是什么?
    我們都知道在groovy中既忆,所有的對(duì)象都實(shí)現(xiàn)了GroovyObject接口
public interface GroovyObject {
public Object invokeMethod(String name, Object args);
public Object getProperty(String property);
public void setProperty(String property, Object newValue);
public MetaClass getMetaClass();
public void setMetaClass(MetaClass metaClass);
}

每個(gè)對(duì)象都有一個(gè)MetaClass驱负,MetaClass是Groovy元概念的核心,它提供了一個(gè)Groovy類的所有的元數(shù)據(jù)患雇,如可用的方法跃脊、屬性列表等.

  • MetaClass的作用
    為類在運(yùn)行時(shí)動(dòng)態(tài)的添加屬性或者方法
    1.添加屬性
class Person1 {}

Person1 person1 = new Person1()
person1.metaClass.sex = 'male'
println person1.sex //輸出結(jié)果:male
person1.sex = "female"
println "the new sex is $person1.sex"  //輸出結(jié)果:the new sex is female

//可以看到 Person1中并沒(méi)有sex這個(gè)屬性,而我們通過(guò)metaClass動(dòng)態(tài)的添加了一個(gè)sex屬性苛吱,并且能夠正確的輸出和修改

2.添加方法

class Person1 {}

Person1 person1 = new Person1()
person1.metaClass.sex = 'male'
person1.metaClass.sexUpperCase = { -> sex.toUpperCase() }
println person1.sexUpperCase()  //輸出結(jié)果:MALE

3.添加靜態(tài)方法

class Person {
    def name
    def age
}

//添加靜態(tài)方法
Person.metaClass.static.createPerson = { String name, int age -> new Person(name: name, age: age) }

def person = Person.createPerson("groovy",6)
println person.name //輸出結(jié)果:groovy
  • 使用場(chǎng)景
    使用每個(gè)類的MetaClass可以不修改任何類本身的代碼酪术,不通過(guò)繼承類來(lái)擴(kuò)展方法來(lái)動(dòng)態(tài)的添加屬性和方法。比如使用第三方庫(kù)的時(shí)候又谋,想要修改某些類拼缝,而類又是final的,即可通過(guò)MetaClass動(dòng)態(tài)的注入屬性和方法變相的達(dá)到修改的目的

  • ExpandoMetaClass.enableGlobally()
    在一個(gè)腳本中動(dòng)態(tài)注入的屬性和方法彰亥,在其它腳本是不能直接使用的咧七,想要使用需要在該腳本中重新注入。這是比較繁瑣的任斋,比如我們想要對(duì)String類型進(jìn)行某一些操作继阻,能不能為String注入方法,全局都能使用呢废酷?答案是能瘟檩,通過(guò)ExpandoMetaClass.enableGlobally()

//定義一個(gè)Person class
class Person {
    String name
    Integer age
}

//定義一個(gè)程序管理類 Application class
class Application {
    static void init() {
        //讓注入的方法全局生效
        ExpandoMetaClass.enableGlobally()
        //注入一個(gè)靜態(tài)方法(假設(shè)這里是為第三方類庫(kù)注入了我們需要的方法)
        Person.metaClass.static.createPerson = { String name, Integer age -> new Person(name: name, age: age) }
    }
}

//定義另外一個(gè)類PersonManager class,在該類中使用Application class中為Person類注入的方法
class PersonManager {
    static Person createPerson(String name, Integer age) {
        //在另外一個(gè)腳本中使用注入的方法
        return Person.createPerson(name, age)
    }
}

//新的入口類 Entry class驗(yàn)證ExpandoMetaClass.enableGlobally()之后注入的方法可以全局調(diào)用
class Entry {
    static void main(String[] args) {
        println '程序開(kāi)始...'
        Application.init() //注入
        Person p = PersonManager.createPerson('groovy', 6)
        println "the name is $p.name,the age is $p.age"

        //輸出結(jié)果:
        /**
         * 程序開(kāi)始...
         * the name is groovy,the age is 6
         */
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者

  • 序言:七十年代末澈蟆,一起剝皮案震驚了整個(gè)濱河市墨辛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌趴俘,老刑警劉巖睹簇,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異寥闪,居然都是意外死亡太惠,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門疲憋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)凿渊,“玉大人,你說(shuō)我怎么就攤上這事“T啵” “怎么了搪锣?”我有些...
    開(kāi)封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)剂癌。 經(jīng)常有香客問(wèn)我淤翔,道長(zhǎng),這世上最難降的妖魔是什么佩谷? 我笑而不...
    開(kāi)封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮监嗜,結(jié)果婚禮上谐檀,老公的妹妹穿的比我還像新娘。我一直安慰自己裁奇,他們只是感情好桐猬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著刽肠,像睡著了一般溃肪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上音五,一...
    開(kāi)封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天惫撰,我揣著相機(jī)與錄音,去河邊找鬼躺涝。 笑死厨钻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的坚嗜。 我是一名探鬼主播夯膀,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼苍蔬!你這毒婦竟也來(lái)了诱建?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤碟绑,失蹤者是張志新(化名)和其女友劉穎俺猿,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蜈敢,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辜荠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抓狭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伯病。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出午笛,到底是詐尸還是另有隱情惭蟋,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布药磺,位于F島的核電站告组,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏癌佩。R本人自食惡果不足惜木缝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望围辙。 院中可真熱鬧我碟,春花似錦、人聲如沸姚建。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)掸冤。三九已至厘托,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間稿湿,已是汗流浹背铅匹。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缎罢,地道東北人伊群。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像策精,于是被迫代替她去往敵國(guó)和親舰始。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容