Kotlin 中如何继承运算符?

How to inherit operators in Kotlin?

我有以下两个 classes:

class Volume(var value: Double, unit: Unit) {
    var unit: Unit = unit
        private set

    enum class Unit(symbol: String){
        MILLILITER("ml"),
        CENTILITER("cl"),
        DECILITER("dl"),
        LITER("l"),
        TEASPOON("tsp"),
        TABLESPOON("tbsp"),
        FLUIDOUNCE("floz"),
        SHOT("jig"),
        GILL("gi"),
        CUP("cup"),
        PINT("pt"),
        QUART("qt"),
        GALLON("gal")
    }
}

class Mass(var value: Double, unit: Unit) {
    var unit: Unit = unit
    private set

    enum class Unit(symbol: String){
        GRAM("g"),
        DECAGRAM("dag"),
        HECTOGRAM("hg"),
        KILOGRAM("kg"),
        OUNCE("oz"),
        POUND("lb")
    }
}

我想为两个 classes 创建运算符以进行基本算术运算,例如:

operator fun inc(): Mass {
    value++
    return this
}

由于两个 classes 将具有相同的运算符逻辑,我不想重复这部分代码。

我的第一个想法是两个 class 都继承自包含运算符的 PhysicalQuantity 接口。在这种情况下,以下代码不起作用,因为 IDE 期望 IPhysicalQuantity 为 return 类型,但类型为 Volume:

interface IPhysicalQuantity() {

    var value: Double
    var unit: IUnit

    operator fun inc(): IPhysicalQuantity {
        value++
        return this
    }
}

fun main() {
    var vol = Volume(10.0, Volume.Unit.CENTILITER)
    vol++
}

与抽象超级 class 相同的问题。

IPhysicalQuantity 接口内部执行此操作的问题是您不想 return 对象作为 inc 方法中的接口类型 IPhysicalQuantity .相反,您想保留其原始类型(VolumeMass),因此您必须在那里使用泛型。但是,我没有找到没有复杂语法和未经检查的转换的方法:

interface IPhysicalQuantity<T : IPhysicalQuantity<T>> {
    var value: Double

    operator fun inc(): T {
        value++
        return this as T
    }
}

class Volume(override var value: Double, unit: Unit): IPhysicalQuantity<Volume>

但是,您可以使用扩展来相当简单地完成此操作,而不必使界面本身通用,如果这对您有用的话:

operator fun <T : IPhysicalQuantity> T.inc(): T {
    value++
    return this
}