美文网首页
Kotlin - 关于类的委托的理解

Kotlin - 关于类的委托的理解

作者: 大丸蛇 | 来源:发表于2019-08-08 14:44 被阅读0次
    • 无论是Kotlin官方的文档和别的地方的文档,你都能发现所有讲类的委托都会举这样一个例子
        interface Base {
            fun print()
        }
    
        // 实现此接口的被委托的类
        class BaseImpl(val x: String) : Base {
            override fun print() {
                Log.d("haha", x)
            }
        }
    
        // 通过关键字 by 建立委托类
        class Derived(b: Base) : Base by b
    
        fun main() {
            val b = BaseImpl("10")
            Derived(b).print() // 输出 10
        }
    
    
    • 上述代码什么意思呢? by子句表示 b 将会在Derived 中内部存储 ,并且编译器将自动生成转发给 b 的所有 print 的方法。通俗的说传入Base的实现类,通过b 创建的实例BaseImpl("10")执行代码,并保存在Derived中。
    • 那可能有人就要问了,我对象都创建出来了,直接调用本身的方法不就行了,干嘛非要绕一圈。
    • 这就要引出一个设计模式的概念 ,代理模式。 Kotlin中的委托,实际上就是Kotlin 用语法糖来实现代理模式的简洁版。
    • 代理模式可以通过代理对象控制另外一个对象,这样的在不修改原先类的情况下,就可以对原先的类增加功能。很好的符合面向对象开闭原则,对修改关闭,对拓展开放。
    • 上述例子的代码就显得很鸡肋了,使用了委托,我们肯定会在原先类做一个扩展,于是就有了下列代码。
        interface Base {
            fun print()
        }
    
        // 实现此接口的被委托的类
        class BaseImpl(val x: String) : Base {
            override fun print() {
                Log.d("haha", x)
            }
        }
    
        // 通过关键字 by 建立委托类
        class Derived(b: Base) : Base by b {
           fun doMyOwnPrint(){
                Log.d("hehe","33")
                print()
           }
        }
    
        fun main() {
            val b = BaseImpl("10")
            Derived(b).doMyOwnPrint() 
          // 输出 hehe33
          // 输出 haha10
        }
    
    
    • 值得一提的是我们用继承,重写也可以达到同样的目的。不过拓展的风险明显要小于继承,基于拓展优先于继承的理念,Kotlin中类的委托是有一定实用价值的(反正我没用过)。
    • 其实除了委托,在kotlin中还有一种语法糖也可以十分简洁的拓展类,那就是扩展(区分“拓展”,但实际上只是一个叫法而已)。
    • 下面直接上代码
     private fun BaseImpl.printMyText() {
            Log.d("33", "")
            print()
        }
               //调用
               val a = BaseImpl()
               a.printMyText();
    
    • 看起来是不是更加简洁呢。

    相关文章

      网友评论

          本文标题:Kotlin - 关于类的委托的理解

          本文链接:https://www.haomeiwen.com/subject/wxhxjctx.html