目录

Kotlin系列(二十二):kotlin原生支持的所谓的委托模式,为何让人这么郁闷呢。。。。


一、前言:

  • 今天学习的内容是Kotlin的委托模式;
  • 首先我想说看到这部分个人很不解,kotlin的委托模式个人认为简直就是鸡肋。
  • OK,其实委托模式也就是代理模式,熟悉Spring的小伙伴将会非常熟悉,因为Spring的基本架构来源于代理的灵活使用。
  • 以下我们便来学习下Kotlin鸡肋般的委托摩丝

二、类委托

  • 委托模式在 Kotlin中是原生支持的,你只需要记住by这个关键字即可。

  • 如类 Derived 可以继承一个接口 Base,并将其所有共有的方法委托给一个指定的对象:

      interface Base {
      		fun print()
      }
    
      class BaseImpl(val x: Int) : Base {
      		override fun print() { print(x) }
      }
    
      class Derived(b: Base) : Base by b
    
      fun main(args: Array<String>) {
      		val b = BaseImpl(10)
      		Derived(b).print() // 输出 10
      }
    
  • 然而,这有什么意思呢?看下反编译为java后的代码

      public final class Derived implements Base {
      	 // $FF: synthetic field
      	private final Base $delegate_0;
    
      	 @NotNull
      	public final Base getB() {
      			return this.b;
      	 }
    
      	 public final void setB(@NotNull Base var1) {
      			Intrinsics.checkParameterIsNotNull(var1, "");
      	 }
    
      	 public Derived(@NotNull Base b) {
      			Intrinsics.checkParameterIsNotNull(b, "b");
      			super();
      			this.$delegate_0 = b;
      	 }
    
      	 public void print() {
      			this.$delegate_0.print();
      	 }
      }
    
    
      public final class DerivedKt {
      	 public static final void main(@NotNull String[] args) {
      			Intrinsics.checkParameterIsNotNull(args, "args");
      			BaseImpl b = new BaseImpl(10);
      			(new Derived((Base)b)).print();
      	 }
      }
    
  • 如上可以看到,其内部仅仅是默认为我们生成了$delegate_0这个字段来接收被代理对象,间接调用而已,但是我们并不能在调用之前或者之后做点什么,虽然我们可以重写,带式重写了我们也拿不到被代理类,我能想到的是这样子写

      package com.anjie.demo
    
      /**
       * Created by 安杰 on 2017/11/2. */
    
       class Derived(var b: Base) : Base by b{
      		override fun print() {
      				this.b.print();
      		}
      }
    
      fun main(args: Array) {
      		val b = BaseImpl(10)
      		Derived(b).print() // 输出 10
    
      }
    
  • 如此便可在执行代理对象方法时做一些额外的处理,但是如此写我还需要by做什么呢?如此不是也可以:

      package com.anjie.demo
    
      /**
       * Created by 安杰 on 2017/11/2. */
       class Derived(var b: Base) : Base {
      		override fun print() {
      				this.b.print();
      		}
      }
    
      fun main(args: Array) {
      		val b = BaseImpl(10)
      		Derived(b).print() // 输出 10
    
      }
    
  • 至此我还是不明白kotlin的by有何意义,难道仅仅是在被代理对象实现的接口中方法太多,通过by来进行可选择性的重写?

  • 目前我也只能想到这一点,以上便是kotlin原生支持的委托模式。