我正在将一些Scala代码迁移到Kotlin,它在类和接口(Scala行话中的特征)的层次 struct 中使用方法线性化.

Kotlin有没有类似的东西? 有什么解决办法吗? https://www.geeksforgeeks.org/trait-linearization-in-scala/

下面是一个使用线性化的简单Scala示例:

class old_Car 
{ 
    def method: String= "old car "
} 
  
// defining new_Car_Designs trait 
trait new_Car_Designs extends old_Car 
{ 
    override def method: String ="Designing-> "+ super.method 
} 
  
// defining new_Car_Part trait 
trait new_Car_Part extends old_Car 
{ 
    override def method: String = "Add new part-> "+ super.method 
} 
  
// defining new_Car_Paint trait 
trait new_Car_Paint extends old_Car 
{ 
    override def method: String = "Repainting-> "+ super.method 
} 
  
// defining new_Car class 
class new_Car extends new_Car_Paint with 
new_Car_Part with new_Car_Designs 
{ 
    override def method: String = "new car-> "+ super.method 
} 
  
// Creating object 
object geekforgeeks 
{ 
    // Main method 
    def main(args: Array[String]) 
    { 
        // new_Car object 
        var car1 = new new_Car 
        println(car1.method) 
    } 
} 

输出:

new car-> Designing-> Add new part-> Repainting-> old car

相关信息:

推荐答案

我认为在Kotlin 使用语言功能不可能做到这一点.这与语言目标是一致的.Kotlin更喜欢组合和委托,而不是继承,尤其是多重继承.

但无论我们使用哪种语言,这个问题都可以用传统的OOP模式来解决--同样是:组合和委托.Kotlin可以提供帮助,生成的代码与原始Scala代码非常相似.从概念上讲,它的工作原理略有不同,对象之间的关系更加明确,但至少对我个人来说,这更好,这更干净:

interface Car {
    val method: String
}

class OldCar : Car {
    override val method = "old car "
}

class OldCarDesigns(private val delegate: Car) : Car by delegate {
    override val method = "Designing-> " + delegate.method
}

class OldCarPart(private val delegate: Car) : Car by delegate {
    override val method = "Add new part-> " + delegate.method
}

class OldCarPaint(private val delegate: Car) : Car by delegate {
    override val method = "Repainting-> " + delegate.method
}

class NewCar private constructor(private val delegate: Car) : Car by delegate {
    constructor() : this(OldCarDesigns(OldCarPart(OldCarPaint(OldCar()))))

    override val method = "new car-> " + delegate.method
}

fun main() {
    val car = NewCar()
    println(car.method)
}

我们不一定需要所有这Car by delegate个成员,因为我们无论如何都要覆盖唯一的成员,但如果我们有更多的成员并希望有 Select 地覆盖它们,那么这是很有帮助的.或者,我们可以引入一个抽象的DelegatingCar来进行授权,但我认为它不会增加太多价值.

汽车连锁店:OldCarDesigns(OldCarPart(OldCarPaint(OldCar())))辆是丑陋的.如果愿意,我们可以创建一个帮助器函数:

fun <T> T.linearize(vararg wrappers: (T) -> T) = wrappers.fold(this) { it, wrapper -> wrapper(it) }

constructor() : this(OldCar().linearize(::OldCarPaint, ::OldCarPart, ::OldCarDesigns))

坦率地说,NewCar美元感觉不太像Kotlin 式的.在Kotlin中,如果新类型的主要/唯一目的是创建其他对象的图形,我们通常会避免定义新类型.我们喜欢工厂的功能,而不是新的类型.

顺便说一句,你的功能顺序对我来说很奇怪:新车--设计--添加部件-油漆-旧车.你的意思不是说新车是基于一辆喷漆的汽车,这反过来又适用于一辆带有附加部件的汽车,这适用于以旧车为基础的重新设计的汽车?当我写我的答案时,它让我有点困惑;

Kotlin相关问答推荐

如果一项工作失败,请继续在Kotlin 等待其他工作/子元素完成

Spring Boot Bean验证器未触发

将文本与文本字段的内容对齐

"Kotlin中的表达式

为什么我的通用Kotlin函数中的这个转换未经判断?

如何在 Kotlin 中为类方法调用传递变量

如何将光标从一个文本字段传递到 Jetpack Compose 中的其他文本字段?

为什么记得不将 StateFlow 转换为特定类型?

判断 Kotlin 变量是否为函数

Kotlin 中的as Long和.toLong()有什么区别?

如何缩短 MaterialTheme.colors.primary?

Kotlin:伴随对象内的函数扩展

即使 Kotlin 的 `Map` 不是 `Iterable`,它如何以及为什么是可迭代的?

Mixin 在 Jackson 中添加 defaultImpl 不起作用

如何在 kotlin @Parcelize 中使用 null

Map.mapTo 到另一个map

创建首选项屏幕时找不到androidx.preference.PreferenceScreen

如何在顶级函数中使用 koin 注入依赖项

Kotlin中的下划线名称是为什么保留的?

以Kotlin为单位的货币数据类型