I'm really confused about the kotlin delegation. Let me describe the regular polymorphism approach here which looks same like the kotlin delgation.

interface Base {
    fun print()
}
class BaseImpl(val x: Int) : Base {
    override fun print() { print(x) }
}
fun main(args: Array<String>) {
    val b : Base = BaseImpl(10)
    b.print() // prints 10
}

I can pass any implemented class of Base interface to b variable to call the method of specified class's object. Then what is the benefit of kotlin's delegation? Which is described here.

interface Base {
    fun print()
}
class BaseImpl(val x: Int) : Base {
    override fun print() { print(x) }
}
class Derived(b: Base) : Base by b // why extra line of code? 
                                   // if the above example works fine without it.
fun main(args: Array<String>) {
    val b = BaseImpl(10)
    Derived(b).print() // prints 10
}

I know this is the simple scenario where the both codes are working fine. There should be a benefit of delegation that's why kotlin introduced it. What is the difference? and how kotlin delegation can be useful? Please give me a working example to compare with polymorphism approach.

推荐答案

还要记住,您并不局限于一个代表.Kotlin实现委托的方式类似于Groovy等语言中的traits个实现.您可以通过委托组合不同的功能.Kotlin的方式也可以被认为更强大,因为您也可以"插入"不同的实现.

interface Marks {
  fun printMarks()
}

class StdMarks() : Marks {
  override fun printMarks() { println("printed marks") }
}

class CsvMarks() : Marks {
  override fun printMarks() { println("printed csv marks") }
}

interface Totals {
  fun printTotals()
}

class StdTotals : Totals {
  override fun printTotals() { println("calculated and printed totals") }
}

class CheatTotals : Totals {
  override fun printTotals() { println("calculated and printed higher totals") }
}

class Student(val studentId: Int, marks: Marks, totals: Totals) 
  : Marks by marks, Totals by totals

fun main(args:Array<String>) {
  val student = Student(1,StdMarks(), StdTotals())
  student.printMarks()
  student.printTotals()
  val cheater = Student(1,CsvMarks(), CheatTotals())
  cheater.printMarks()
  cheater.printTotals()
}

输出:

printed marks
calculated and printed totals
printed csv marks
calculated and printed higher totals

You can't do this with inheritance.

Kotlin相关问答推荐

UByte范围. Min_UTE.. UByte.MAX_UTE不符合预期

用普通Kotlin理解Gradle的Kotlin DSL'""

在Kotlin中,我是否可以访问已知的WHEN子句值?

捕捉异常是Kotlin协程中的反模式吗?

collectAsState 未从存储库接收更改

Spring Boot Kotlin 数据类未使用 REST 控制器中的默认值初始化

第二个协程永远不会执行

为什么没有remember 的 mutableStateOf 有时会起作用?

Kotlin:如何在活页夹中返回正在运行的服务实例?

Android Studio 4.0.0 Java 8 库在 D8 和 R8 构建错误中脱糖

Kotlin如何分派invoke操作符?

Kotlin get字段注释始终为空

Android Studio 将 Java 转换为 Kotlin 错误无法推断此参数的类型

如何在Android Studio 4.1中默认启用Kotlin Android扩展

将 Double 转换为 ByteArray 或 Array Kotlin

Kotlin类型安全类型别名

Recyclerview: listen to padding click events

在 Android 12 (SDK 31) 中获取 android.app.ForegroundServiceStartNotAllowedException

Kotlin - 错误:Could not find or load main class _DefaultPackage

Android Jetpack Compose - 图像无法zoom 到框的宽度和高度