第七章、Groovy面向对象

1、定义类和脚本

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

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

  • /**
     * 声明变量
     * @author liangchen* @date 2020/11/8
     */
    class DeclareVariableDemo {
    
        // 成员变量
        public fieldWithModifier
        String typedField
        def untypeField
        protected field1, field2, field3
        private assignedField = new Date()
        static classField
        public 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() == 4
    
            GroovyAssert.shouldFail(ClassCastException) {
                Float areaofCircleRadiusOne = PI
            }
        }
    
        def someMethods(){
            // 本地变量
            def localUntypedMethodVar = 1
    
            int localTypedMethodVar = 1
    
            def localVarWithoutAssigment , andAnotherOne
    
        }
    
        def localvar = 1,boundvar1 = 1
        def someMethod(){
            def localMethodVar = 1
            boundvar2 = 1
        }
    
    
    
    }
    
    
  • 没有字段默认调用方法

  • /**
     * 引用成员变量
     * @author liangchen* @date 2020/11/8
     */
    class ReferenceFieldDemo {
        static void main(String[] args) {
            def counter = new Counter()
            counter.count = 1
            assert counter.count == 1
    
            def fieldName = 'sum'
            counter[fieldName] = 2
            assert counter.sum == 2
    
            // 没有值,就调用get方法
            def pretender = new PretendFieldCounter()
            assert pretender.isNoField == 'pretend value'
    
            assert pretender.count == 0
            //调用set方法 count ==1
            pretender.isNoFieldEither = 'just to increase counter'
            // 调用set方法  count==2
            pretender.aaa = 1
            assert pretender.count == 2
        }
    }
    class Counter{
        public count =0
        public sum = 0
    }
    
    class PretendFieldCounter {
        public count = 0
    
        Object 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 ==1
      
              if (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, product
      
          CallConstructorDemo(name, product) {
              this.name = name
              this.product = product
          }
      
          // Java 的方式
          def first = new CallConstructorDemo('Canoo', "ULC")
      
          // as 语法
          def second = ['Canoo','ULC'] as CallConstructorDemo
      
          // 自己数组元素
          CallConstructorDemo third = ['Canoo', 'ULC']
      }
      
      
      class CallConstructorNameDemo{
          String name, product
      
          public 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 = 1121
              canoo.address.town = '岳麓区'
              canoo.address.state = '长沙'
              // 查找匹配字符
              assert canoo.dump() =~ /apple/
              // 查找匹配字符
              assert canoo.address.dump() =~/1121/
              println canoo.address.dump()
          }
      }
      class Vendor {
          public String name
          public String product
      
          public Address address =new Address();
      }
      class Address{
          public String  street, town , state
          public 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.BigInteger
      
      import 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 =1
            Object 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 typed
    				
            def 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, lastname
              String 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.value
               assert 100 == beanss.@value
      
           }
      
          /**
           * 获取成员变量,使用.@
           *
           */
      
          static  class DoublerBean {
              public value
      
              void 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 someProperty
              public someField
              private somePrivateField
          }
      
          static void main(String[] args) {
             def obj = new ClassWithProperties()
              def store = []
              obj.properties.each { property ->
                  store += property.key
                  store += property.value
              }
              assert store.contains('someProperty')
              assert store.contains('someField')  == false
              assert store.contains('somePrivateField') == false
              assert 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 items
            Date date
        }
    
        static class LineItem{
            Product product
            int count
            int total(){
                return product.dollar * count
            }
        }
    
        static class Product {
            String name
            def 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 *:map
            def map = [a:1, b:2]
            assert [a:1, b:2, c:3] == [c:3, *:map]
        }
    
    }
    
    

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

6、总结

  1. 方法、成员变量、局部变量定义(对比java来说的)
  2. groovybean定义
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值