Kotlin 在抽象中访问非抽象函数中的抽象函数 class

Kotlin accessing an abstract function in a non abstract function in abstract class

我有一个 class 基本上是这样的:

abstract class BaseContinuousSingleObjectiveFitnessFunction {

    // Invoke should compute some function, like f(x) = x^2 + 3x + 5
    abstract fun invoke(x: List<Double>): Double

    // This is supposed to return an object deriving this one where 
    // invoke actually returns 1/(1+f(x)), essentially reversing the function.
    fun reverse(): BaseContinuousSingleObjectiveFitnessFunction =
            object: BaseContinuousSingleObjectiveFitnessFunction() {
                override operator fun invoke(x: List<Double>): Double {
                    var denominator = 1.0 + super.invoke(x)
                    if (denominator.absoluteValue < Double.MIN_VALUE * 10)
                        denominator += denominator.sign * Double.MIN_VALUE * 10

                    return 1.0 / denominator
                }
            }
}

问题是 invoke 是抽象的,因此编译器会抱怨 Abstract member cannot be accessed directly. 是正确的。

然而任何派生我的 class 的 class 显然将被迫实现 invoke 所以从概念上讲,在那些 class 中调用 reverse 应该没有问题es 但在这个基础 class 中有实现。 reverse 的实现虽然严格来说 依赖于 invoke,但不能在不提供 class 的任何 class 中调用此实现=12=] 无论如何。

最简单的解决方案是在每个 class 中复制 reverse 的代码,但我不想有代码重复。

所以我的问题是,究竟什么是一种优雅的方式来做我想做的事情:提供一个定义明确的行为 (reverse),它使用尚未定义的行为 (invoke),但这将调用reverse时定义100%?

问题是 super.invoke(x) 试图调用直接从 BaseContinuousSingleObjectiveFitnessFunction 派生的对象的超级方法。由于没有超级实现,你会得到错误。您可能想保留对原始函数的引用:

    fun reverse(): BaseContinuousSingleObjectiveFitnessFunction {
        val originalFunction = this
        return object: BaseContinuousSingleObjectiveFitnessFunction() {
            override operator fun invoke(x: List<Double>): Double {
                var denominator = 1.0 + originalFunction.invoke(x)
                if (denominator.absoluteValue < Double.MIN_VALUE * 10)
                    denominator += denominator.sign * Double.MIN_VALUE * 10

                return 1.0 / denominator
            }
        }
    }