我有一个基本上是这样的类:
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.
是真的。
然而,任何派生我的类的类显然都将被迫实现invoke
,因此从概念上讲,在这些类中调用reverse
但在这个基类中实现应该没有问题。reverse
的实现虽然严格地说依赖于invoke
,但该实现不能在任何不提供invoke
的类中调用。
最简单的解决方案是在每个类中复制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
}
}
}