为什么只有接口可以委托给kotlin?
问题描述:
我看到过几个类似的问题,但没有一个解释为什么委托仅限于接口?为什么只有接口可以委托给kotlin?
大多数时间在实践中我们有一些实际上根本没有接口的东西,它是一个只实现一些功能或实现一个抽象类的类。
是否有任何根本性的限制,迫使它仅限于接口,或者我们可以期望kotlin在未来拥有无限制的授权?
如果我们想使用组合不继承来扩展类的功能,这将特别有用。
class A {}
class B(val a: A) : A by a {}
答
当您委派一个接口时,该类仍然实现该接口。所以为了一致性,如果你可以委托一个类,它应该以同样的方式工作。即
class A(x: Int) {
fun foo() = x
}
class B(val a: A) : A by a {}
需要编译成
class B(val a: A) : A {
override fun foo() = a.foo()
}
除了这不起作用:
foo
不open
并且不能被重写。您需要调用
A
的构造函数。class B(val a: A) : A(a.x)
也不会帮助:x
不是A
的成员。equals
和hashCode
怎么样?他们是否被委派?任何一个决定都会导致怪异的后果。
1.所以它不应该试图覆盖它。应该自动委托可重写的方法('open'或'abstact')。 2.所以'B'应该像往常一样将构造参数传递给'A'。 3.因为每个接口隐含地扩展了'Any',因此具有'equals','hashCode'和'toString',所以Kotlin作者必须为接口委派做出这个决定。 – Jesse
当然,这是一组可能的答案。但是,你不会“使用组合不继承的方式扩展类的功能”;你有一个非常奇怪的组合和继承组合,并且打开'A'中的方法而不改变它的行为(例如,因为你发现'C'需要重写它)可以改变'B'的行为。 –