У меня есть класс, который в основном такой:
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
), но это будет на 100% определен в тот момент, когда вызывается reverse
?