Kotlin委托

161 阅读2分钟

正文开始

我认为Kotlin的委托与组合模式(composition pattern)相当接近,所以在认识委托前,先来回顾一下Java的组合模式吧!

组合模式小Demo

interface  Animal {
    fun  feed ()
}

class  Dog  :  Animal {

    override  fun  feed () {
        println ( " 吃狗粮 " )
    }

}

class  Cat  :  Animal {

    override  fun  feed () {
        println ( " 吃猫粮 " )
    }

}

class  AnimalHost ( val  animal :  Animal ) {

    fun  feed () {
        animal.feed()
    }
}


fun  main ( args :  Array < String >) {

    val dog =  Dog ()
    val dogHost =  AnimalHost (dog)
    animalHost.feed()
    // 吃狗粮

    val cat =  Cat ()
    val catHost =  AnimalHost (cat)
    catHost.feed()
    // 吃猫粮

}

俗话说:

「多用组合,少用继承。」

我记得这是在深入浅出设计模式这本书中出现过的警语,虽然继承是物件导向的重点之一,但过多的继承反而会让程式码难以维护……(真是难以体会呀?)

总之你会因为各种不同的需求,去创造不同的子类别,并且覆写相关的方法。当类别属性变多,你要覆写的就会变多;当有几个子类别中大部分的属性都相同,你还是需要多创造几个子类别,然后疯狂的覆写。

使用委托实作

使用组合模式时,当你要启动执行者的方法时,还是得依赖执行者的类别方法;换句话说,执行的方法需要被呼叫,执行者方法才会被呼叫。 在Kotlin中使用委托就不一样了,你可以直接去执行方法:

interface  Animal {
    fun  feed ()
}

class  Dog  :  Animal {

    override  fun  feed () {
        println ( " 吃狗粮 " )
    }

}

class  Cat  :  Animal {

    override  fun  feed () {
        println ( " 吃猫粮 " )
    }

}

class  AnimalHost ( animal :  Animal ) :  Animal by animal


fun  main ( args :  Array < String >) {

    val dog =  Dog ()
    val dogHost =  AnimalHost (dog)
    animalHost.feed()
    // 吃狗粮

    val cat =  Cat ()
    val catHost =  AnimalHost (cat)
    catHost.feed()
    // 吃猫粮

}

上述代码AnimalHost没有任何代码但他实际上委托了animal的所有属性和方法,所以你调用Animal类的feed的方法时相当于调用你传入的介质的方法,会委托给你传入的介质的方法。

在kotlin中还支持多个委托代码如下:

interface  Clothes {

    fun  wearClothes ()
}


interface  Shoes {

    fun  wearShoes ()
}

class  Jack  :  Clothes {

    override  fun  wearClothes () {
        println ( " 穿夹克 " )
    }
}

class  Sweater  :  Clothes {

    override  fun  wearClothes () {
        println ( " 穿毛衣 " )
    }
}

class  Leather  :  Shoes {

    override  fun  wearShoes () {
        println ( " 穿皮鞋 " )
    }
}

class  Sports  :  Shoes {

    override  fun  wearShoes () {
        println ( " 穿运动鞋 " )
    }
}

class  Person ( clothes : Clothes , shoes :  Shoes ) :  Clothes by clothes, Shoes by shoes


fun  main ( args :  Array < String >) {

    val jack =  Jack ()
    val leather =  Leather ()
    val man =  Person (jack, leather)
    man.wearClothes()
    man.wearShoes()
  
    val sweater =  Sweater ()
    val sports =  Sports ()
    val man2 =  Person (sweater, sports)
    man2.wearClothes()
    man2.wearShoes()

}