文章目录

  • 1、定义类和脚本
    • 1.1、定义成员变量和本地变量
    • 1.2、定义方法和参数
    • 1.3、?. 判断是否连续为空 (短路运算符)
    • 1.4、构造器
  • 2、组织类和脚本
    • 2.1、文件与类关系
    • 2.2、在包组织类
    • 2.3、考虑更深classpath(类路径)
  • 3、面向对象的高级特性
    • 3.1、使用继承
    • 3.2、使用接口
    • 3.3、多方法(重载)
    • 3.4、使用trait
  • 4、GroovyBeans使用
    • 4.1、声明bean
    • 4.2、beans运行特征
    • 4.3、在任何类中使用bean 的方法
    • 4.4、Field、accessors、maps and Expando
  • 5、使用高级语法特性
    • 5.1、使用GPaths查询对象
    • 5.2、注入*操作
    • 5.3、利用命令链来使用精确语法
  • 6、总结

1、定义类和脚本

1.1、定义成员变量和本地变量

  • 定义成员变量, 本地变量

  • /*** 声明变量* @author liangchen* @date 2020/11/8*/
    class DeclareVariableDemo {// 成员变量public fieldWithModifierString typedFielddef untypeFieldprotected field1, field2, field3private assignedField = new Date()static classFieldpublic static final String CONSTA = 'a', CONSTB = 'b'static void main(String[] args) {// ClassCastException 类转换异常final String PI = '3.14'assert PI.class.name == 'java.lang.String'assert PI.size() == 4GroovyAssert.shouldFail(ClassCastException) {Float areaofCircleRadiusOne = PI}}def someMethods(){// 本地变量def localUntypedMethodVar = 1int localTypedMethodVar = 1def localVarWithoutAssigment , andAnotherOne}def localvar = 1,boundvar1 = 1def someMethod(){def localMethodVar = 1boundvar2 = 1}}
  • 没有字段默认调用方法

  • /*** 引用成员变量* @author liangchen* @date 2020/11/8*/
    class ReferenceFieldDemo {static void main(String[] args) {def counter = new Counter()counter.count = 1assert counter.count == 1def fieldName = 'sum'counter[fieldName] = 2assert counter.sum == 2// 没有值,就调用get方法def pretender = new PretendFieldCounter()assert pretender.isNoField == 'pretend value'assert pretender.count == 0//调用set方法 count ==1pretender.isNoFieldEither = 'just to increase counter'// 调用set方法  count==2pretender.aaa = 1assert pretender.count == 2}
    }
    class Counter{public count =0public sum = 0
    }class PretendFieldCounter {public count = 0Object get(String name) {return 'pretend value'}void set(String name, Object value) {count++}
    }

1.2、定义方法和参数

  • 可以是确定类型和不确定类型

  • /*** 声明方法 和入参类型* @author liangchen* @date 2020/11/8*/
    class ClassWithTypedAndUntypedMethods {static void main(args) {def some = new ClassWithTypedAndUntypedMethods()some.publicVoidMethod()assert 'hi' == some.publicUntypedMethod()assert 'ho' == some.publicTypeMethod()def classWith = new ClassWithTypedAndUntypedMethodParams()// 入参类型assert 'untyped' == classWith.method(1)assert 'typed' == classWith.method('whatever')assert  'two args' == classWith.method(1,2)}/*** 没有返回值*/void publicVoidMethod(){}/*** 没有返回类型方法* @return*/def publicUntypedMethod(){return 'hi'}/*** 有返回值类型* @return*/String publicTypeMethod(){return 'ho'}private static final void combinedMethod(){}
    }class ClassWithTypedAndUntypedMethodParams {static void main(args) {}/*** 不确定类型入参* @param arg* @return*/static method(arg){return 'untyped'}/*** 有类型入参* @param arg* @return*/static method(String arg) {return 'typed'}/*** 两个参数* @param arg1* @param arg2* @return*/static method(arg1, Number arg2) {return 'two args'}
    }
  • map, list 数组入参

    • /*** list map 入参* @author liangchen* @date 2020/11/9*/
      class Summer {static void main(String[] args) {def summer = new Summer();assert  2 == summer.sumWithDefualts(1,1)assert 3 == summer.sumWithDefualts(1, 1, 1)assert 2 == summer.sumWithList([1,1])assert 3 == summer.sumWithList([1,1,1])assert 2 == summer.sumWithOptionals(1,1)assert 3 == summer.sumWithOptionals(1,1,1)assert 2 == summer.sumNamed(a:1, b:1)assert 3 == summer.sumNamed(a: 1, b: 1, c: 1)assert 1 == summer.sumNamed(c:1)}def sumWithDefualts(a, b, c = 0) {return a + b + c}def sumWithList(List args) {return args.inject (0){sum, i -> sum +=i}}def sumWithOptionals(a, b, Object[] optionals) {return a + b + sumWithList(optionals.toList())}
      /*** 入参为map* @param args* @return*/def sumNamed(Map args) {// 不存在设置0['a','b','c'].each {args.get(it, 0)}return args.a + args.b + args.c}
      }
      

1.3、?. 判断是否连续为空 (短路运算符)

  • 避免连续判空

    • /*** ?. 避免空指针,连续判空* @author liangchen* @date 2020/11/9*/
      class ProtectionNPEs {static void main(String[] args) {def map = [a: [b: [c: 1]]]assert  map.a.b.c ==1if (map && map.a && map.a.x) {assert map.a.x.c == null}try {assert map.a.x.c == null} catch (NullPointerException ignore) {}assert map?.a?.x?.c==null}}

1.4、构造器

  • 指定成员变量名和其他方式

    • /*** @author liangchen* @date 2020/11/9*/
      class CallConstructorDemo {String name, productCallConstructorDemo(name, product) {this.name = namethis.product = product}// Java 的方式def first = new CallConstructorDemo('Canoo', "ULC")// as 语法def second = ['Canoo','ULC'] as CallConstructorDemo// 自己数组元素CallConstructorDemo third = ['Canoo', 'ULC']
      }class CallConstructorNameDemo{String name, productpublic static void main(String[] args) {// 可以指定成员变量名new CallConstructorNameDemo()new CallConstructorNameDemo(name: 'Canoo')new CallConstructorNameDemo(product:'ULC')new CallConstructorNameDemo(name: 'Canoo', product: 'ULC')}
      }

2、组织类和脚本

2.1、文件与类关系

  • 一个文件有多个类

    • /*** 一个groovy 有两个类* @author liangchen* @date 2020/11/9*/
      class MultipleClassDemo {static void main(String[] args) {def canoo = new Vendor()canoo.name = 'jack'canoo.product='apple'canoo.address.street = '天顶乡'canoo.address.zip = 1121canoo.address.town = '岳麓区'canoo.address.state = '长沙'// 查找匹配字符assert canoo.dump() =~ /apple/// 查找匹配字符assert canoo.address.dump() =~/1121/println canoo.address.dump()}
      }
      class Vendor {public String namepublic String productpublic Address address =new Address();
      }
      class Address{public String  street, town , statepublic int zip
      }

2.2、在包组织类

  • 跟java类似

  • 默认导入语句

    • import java.lang.*import java.util.*import java.io.*import java.net.*import groovy.lang.*import groovy.util.*import java.math.BigIntegerimport java.math.BigDecimal
  • 导入设置别名 ( 避免相同类名,不同包下,识别更快)

    • 需要继承类

    • package com.jack.groovy.ch7.thirdparty/*** @author liangchen* @date 2020/11/10*/
      class MathLib {Integer twice(Integer value) {return value * 3}Integer half(Integer value) {return value / 2}
      }
    • 继承类

      • package com.jack.groovy.ch7// 这里使用 as 为这个导入设置别名
        import com.jack.groovy.ch7.thirdparty.MathLib as TypeMathLib
        /*** @author liangchen* @date 2020/11/10*/
        class MathLib extends TypeMathLib  {/*** 订正 2倍* @param value* @return*/Integer twice(Integer value) {return value * 2}static void main(String[] args) {def mathlib = new MathLib()assert 10 == mathlib.twice(5)assert  2 == mathlib.half(5)}}

2.3、考虑更深classpath(类路径)

3、面向对象的高级特性

3.1、使用继承

  • 类似java

3.2、使用接口

  • 类似java

3.3、多方法(重载)

  • 方法名一样,入参不一样

  • /*** 方法重载* @author liangchen* @date 2020/11/10*/
    class Multimethod {def oracle(Object o) {return 'object'}def oracle(String o) {return 'string'}static void main(String[] args) {def multi =  new Multimethod()Object x =1Object y = 'foo'assert 'object' == multi.oracle(x)assert 'string' == multi.oracle(y)}}

3.4、使用trait

  • trait 关键字

  • /*** trait 有点类似 接口,只不过他有一些方法和属性, 应该说是抽象类和接口结合体* @author liangchen* @date 2020/11/10*/
    class TraitDemo {trait HashId{long id}trait HasVersion{long version}trait Persistent{boolean save(){println "saving ${this.dump()}"}}trait  Entity implements Persistent ,HashId, HasVersion{boolean save(){version++Persistent.super.save()}}class Publication implements  Entity{String title}class Book extends  Publication{String isbn}static void main(String[] args) {Entity gina = new Book(id:1,version: 1,title: 'gina', isbn: "11111")gina.save()assert gina.version == 2}
    }
    

4、GroovyBeans使用

4.1、声明bean

  • /*** groovy bean 定义* @author liangchen* @date 2020/11/10*/
    class MyBeanDeom {static class MyBean implements Serializable{String myprop//没有定义类型def untyped//定义类型String typeddef item1, item2//赋值初始值def assigned = 'default value'}static void main(String[] args) {MyBean myBean =  new MyBean()assert 'default value' == myBean.getAssigned()myBean.setUntyped('some value')assert 'some value' == myBean.getUntyped()}
    }

4.2、beans运行特征

  • 获取field(成员变量)和方法

    • /*** 调用groovy方法* @author liangchen* @date 2020/11/10*/
      class CallGroovyWayDemo {static class MrBean {String firstname, lastnameString getName (){return "$firstname $lastname"}}static void main(String[] args) {def bean = new MrBean(firstname: 'Rowan')bean.lastname = 'Jack'// 自动调用name --> getName 方法assert 'Rowan Jack' == bean.name//获取成员变量,使用.@def beanss = new DoublerBean(value: 100)assert 200 == beanss.valueassert 100 == beanss.@value}/*** 获取成员变量,使用.@**/static  class DoublerBean {public valuevoid setValue(value) {this.value = value}def getValue() {value * 2}}
      }

4.3、在任何类中使用bean 的方法

  • 获取def 修饰的field 字段

    • /*** 获取bean的属性* 获取def 修饰的变量* @author liangchen* @date 2020/11/10*/
      class GDKBeanProperties {static class ClassWithProperties{def somePropertypublic someFieldprivate somePrivateField}static void main(String[] args) {def obj = new ClassWithProperties()def store = []obj.properties.each { property ->store += property.keystore += property.value}assert store.contains('someProperty')assert store.contains('someField')  == falseassert store.contains('somePrivateField') == falseassert store.contains('class')assert obj.properties.size() == 2}}

4.4、Field、accessors、maps and Expando

  • Expando

    • /*** 动态扩展属性和方法 Expando* @author liangchen* @date 2020/11/10*/
      class ExpandoDemo {static void main(String[] args) {def boxer = new Expando()assert null == boxer.takeThis// 赋值 takeThis 不存在的值boxer.takeThis = 'jack'assert 'jack' == boxer.takeThis// 定义方法boxer.fightBack = {times -> delegate.takeThis * times}assert  'jackjack' == boxer.fightBack(2)}
      }

5、使用高级语法特性

5.1、使用GPaths查询对象

  • /***  GPath 解析* @author liangchen* @date 2020/11/10*/
    class GPathInvoiceDemo {static class Invoice{List itemsDate date}static class LineItem{Product productint countint total(){return product.dollar * count}}static class Product {String namedef dollar}static void main(String[] args) {def ulcDate = Date.parse('yyyy-MM-dd', '2015-01-01')def otherDate = Date.parse('yyy-MM-dd', '2015-02-02')def ulc = new Product(dollar: 1499, name: 'ULC')def ve = new Product(dollar: 499, name: 'Visual Editor')def invoices = [new Invoice(date: ulcDate, items: [new LineItem(count: 5, product: ulc),new LineItem(count: 1, product: ve)]),new Invoice(date: otherDate, items: [new LineItem(count: 4, product: ve)])]// lineItem 平铺,拆开def allItems = invoices.items.flatten()// 循环调用 total方法assert [5*1499, 499, 4*499] == allItems*.total()// 查询 数量大于 7000的assert ['ULC'] == allItems.grep{it.total() > 7000}.product.name// product == ulc , date日期变成字符串def searchDates = invoices.grep { it.items.any{it.product == ulc}}.date*.toString()assert [ulcDate.toString()] == searchDates}
    }

5.2、注入*操作

  • /***    * 号操作* @author liangchen* @date 2020/11/10*/
    class SpreadDemo {def getList(){return [1,2,3]}def sum(a, b, c) {return a + b + c}static void main(String[] args) {def spread =  new SpreadDemo()// 直接调用getList 方法获取到值作为sum的参数assert 6 == spread.sum(*spread.list)// 直接使用*变量数组def range = (1..3)assert [0,1,2,3] == [0, *range]// 或者map 或者map *:mapdef map = [a:1, b:2]assert [a:1, b:2, c:3] == [c:3, *:map]}}

5.3、利用命令链来使用精确语法

6、总结

  1. 方法、成员变量、局部变量定义(对比java来说的)
  2. groovybean定义

第七章、Groovy面向对象相关推荐

  1. java学习笔记-第七章:面向对象编程(基础部分)

    第七章:面向对象编程(基础部分) 总体内容 类与对象 引出类与对象 类与对象概述 类与对象的关系示意图 属性概念及其细节 类与对象快速入门案例 对象内存布局 类与对象内存分配机制 引申:java内存的 ...

  2. 第七章、 面向对象基础--下(续) 内部类、枚举、注解

    文章目录 内容 学习目标 第七章 面向对象基础--下(续) 7.7 内部类 7.7.1 概述 7.7.1 非静态成员内部类 练习1:语法练习题 练习2:简单面试题 练习题3:高难面试题 7.7.2 静 ...

  3. Python基础——PyCharm版本——第七章、面向对象编程

  4. 使用java实现面向对象 第七章

    第七章 多线程 一.Thread类和Runnable接口 1.在java.lang包中定义了Runnable接口和Thread类. Runnable接口中只定义了一个方法,它的格式为: public ...

  5. 深入.NET平台和C#编程笔记 第七章 深入理解多态

    第七章 深入理解多态 1.里氏替换原则: 在一个软件系统中,如果子类出现在父类出现的位置,而整个软件功能又没有影响,那么咱们称为里氏替换. 父类变量指向子类对象!! 2.Is 和as Is 做类型判定 ...

  6. java第七章jdbc课后简答题_java学习路线流程

    第一阶段JavaSE: 第一章:jdk的安装与配置 第二章:Java基础语法: 变量.常量.数据类型.关键字 运算符和表达式:运算符:+.-.*./ 表达式:正则表达式 关系及逻辑运算符:关系运算符: ...

  7. 【设计模式】第七章 享元模式

    第七章 享元模式 文章目录 第七章 享元模式 一.介绍 二.结构 三.实现 一.介绍 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建过多的对象将会耗费很多的系统资源,它是 ...

  8. 【JAVA SE】第七章 继承和多态

    第七章 继承和多态 文章目录 第七章 继承和多态 一.继承 1.概念 2.继承的特性 2.继承关键字 3.构造器 4.子类重写父类方法的规则 二.多态 1.概念 2.多态的优点 3.多态存在的三个必要 ...

  9. 【系统分析师之路】第七章 复盘系统设计(业务流程建模)

    [系统分析师之路]第七章 复盘系统设计(业务流程建模) 复盘系统设计之业务流程建模 [系统分析师之路]第七章 复盘系统设计(业务流程建模) 前言部分 历年真题考点分析 1)考点分析 2)重要知识点 第 ...

  10. python归一化 增大差异_简学Python第六章__class面向对象编程与异常处理

    Python第六章__class面向对象编程与异常处理 欢迎加入Linux_Python学习群 群号:478616847 目录: 面向对象的程序设计 类和对象 封装 继承与派生 多态与多态性 特性pr ...

最新文章

  1. Windows上IDEA搭建最新Spark2.4.3源码阅读及调试的开发环境
  2. R语言构建仿真数据库(sqlite)并使用dplyr语法和SQL语法查询数据库、将dplyr语法查询语句翻译为SQL查询语句
  3. ES6 模块加载export 、import、export default 、import() 语法与区别,笔记总结
  4. 【转】反病毒攻防研究第002篇:利用缝隙实现代码的植入
  5. unittest框架学习笔记
  6. Failed to execute goal on project xxx: Could not resolve dependencies for project com
  7. “约见”面试官系列之常见面试题之第五十五篇之清除浮动的方法(建议收藏)
  8. 学会这些 Python 美图技巧,就等着女朋友夸你吧
  9. JQuery:常用方法一览
  10. Meteor资源国外优秀web APP 收藏
  11. 蓝桥杯 后缀字符串 map
  12. Quartz 配置详解
  13. 计算机数据类型误差怎么解决,测绘数据常见误差类型及处理方法
  14. 资料1:中小企业局势分析
  15. 【读书总结】《三体》—— 生存是文明的第一需要
  16. 通话录音自动上传功能
  17. win7 AnkhSVN 安装报错
  18. Vue 3 + Vite + Eslint + prettier + husky + lint-staged 搭建基础项目
  19. 使用disk genius合并C盘和D盘
  20. 判断某天是该年中的多少天

热门文章

  1. python输入esc退出循环_如何用Esc键停止GhPython或者RhinoPython脚本运行
  2. java使用cmd编译中文时错误,解决Notepad++编写的Java程序在cmd窗口编译时中文注释报错问题...
  3. SolidWorks二次开发-关于录制宏保存的格式
  4. 快捷支付对银行的冲击及银行应对办法
  5. 美化微信小程序的界面--微信小程序开发中使用vant的完整步骤
  6. 手机屏幕常见故障_手机测试常见问题总结!
  7. 707-详解32位Linux系统内存地址映射
  8. 达人评测锐龙r7 6800u和r7 5800u差距 r76800u和r75800u对比
  9. The Preliminary Contest for ICPC Asia Shanghai 2019 BDL
  10. 8、ARM嵌入式系统:UART初始化