“这个”在这方面没有定义

我如何解决以下情况?

interface I class A(i: I) class C : I, A(this) // << --- 'this' is not defined in this context 

总之,我想将类实例传递给超类的构造函数。
Kotlin有可能吗?

PS所有的答案都是好的,技术上是正确的。 但是让我们举一个具体的例子:

 interface Pilot { fun informAboutObstacle() } abstract class Car(private val pilot: Pilot) { fun drive() { while (true) { // .... if (haveObstacleDetected()) { pilot.informAboutObstacle() } // .... } } fun break() { // stop the car } } class AutopilotCar : Pilot, Car(this) { // For example, Tesla :) override fun informAboutObstacle() { break() // stop the car } } 

这个例子看起来不太有意思,为什么我不能用面向对象的语言来实现呢?

不,这在JVM上是不可能的。 this只有在超类被初始化后才可用。

https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.10.2.4

类myClass的实例初始化方法(§2.9.1)在局部variables0中将新的未初始化对象视为其参数。在该方法调用myClass或其直接超类的另一个实例初始化方法之前,该方法的唯一操作对此进行分配在myClass中声明的字段。

因此,在调用超类构造函数之前禁止字节码指令aload 0在堆栈上推送this 。 这就是为什么它不能作为超级构造函数的parameter passing。

Kotlin诞生于JVM语言,旨在最大程度地实现与Java代码的互操作性以及最小的语言function开销。 虽然Kotlin可能选择以不同的方式编排对象初始化,但它会在混合的Java-Kotlin类层次结构中产生问题,并增加大量开销。

在诸如Java , C#或Swift之类的OOP语言的良好传统中,Kotlin不允许在调用超类初始化之前泄漏this引用。 在你的特殊情况下,你只是存储引用,但在一个稍微不同的情况下,超类代码可能会尝试使用接收的对象,该对象仍然是未初始化的。

作为语言不允许的一个具体例子,考虑一个例子,其中A是你使用的库中的一个类,这个规则不起作用。 你通过this像你一样,事情工作正常。 后来你将库更新到一个更新的版本,并且恰巧添加了一些像i.toString()那样的良性的东西给它的构造函数。 它不知道它实际上正在调用自己重写的方法。 您的toString()实现会观察所有不variables,例如未初始化的val

这种设计会遇到其他问题,而不仅仅是现在正在挣扎的循环初始化依赖。 简而言之, A类期望:

A和我

但相反,你创建这个:

C是我

A依赖于typesI的协作者对象。 它不认为自己是合作者。 这可能会带来各种奇怪的错误。 例如,您的C.toString()可能委托给super.toString()A.toString()ACsuper )可能调用I.toString() ,导致StackOverflowError

我不能说你的问题A是否被设计用于扩展,这将使得C : A部分正确,但是你绝对应该把A解开。