Object Kotlin匿名对象继承自基类,但保留派生类属性

Object Kotlin匿名对象继承自基类,但保留派生类属性,object,kotlin,inheritance,Object,Kotlin,Inheritance,我有一个问题,我不知道如何优雅地理解: 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 take a function

我有一个问题,我不知道如何优雅地理解:

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 take a function that will be called on the result of invoke
    // and return an object derived from this one that has its invoke overriden to call
    // the new function on the result of the original one.
    fun modify(f: (Double) -> Double): BaseContinuousSingleObjectiveFitnessFunction {
        val originalFunction = this
        return object : BaseContinuousSingleObjectiveFitnessFunction() {
            override operator fun invoke(x: List<Double>): Double = f(originalFunction(x))
        }
    }
}
然后我想调用modify:

val f1 = XTimesA(a = 5.0)
println(f1.a) // Works

val f2 = f1.modify { it.pow(2) }
println(f2.a) // This fails because it is not recognized as deriving XTimesA

有没有办法不将粘贴
modify
复制到每个派生类中,但仍保留对属性的访问权限?

如果希望能够访问所有继承级别上的属性值,则必须将属性提升到基类:

abstract class BaseContinuousSingleObjectiveFitnessFunction<Value>(val value: Value) {

    abstract fun invoke(x: List<Value>): Value

    fun modify(f: (Value) -> Value): BaseContinuousSingleObjectiveFitnessFunction<Value> {
        val originalFunction = this
        return object : BaseContinuousSingleObjectiveFitnessFunction<Value>() {
            override operator fun invoke(x: List<Value>): Value = f(originalFunction(x))
        }
    }
}
抽象类BaseContinuousSingleObjectiveFitnessFunction(val值:value){
抽象乐趣调用(x:List):值
fun modify(f:(Value)->Value):BaseContinuousSingleObjectiveFitnessFunction{
val originalFunction=此
返回对象:BaseContinuousSingleObjectiveFitnessFunction(){
重写运算符fun invoke(x:List):值=f(原始函数(x))
}
}
}
Value
在这里是一种通用类型,用于
Double
不适用于所有情况的情况。如果所有值都是Double类型,则类不需要此类型参数。

您可以使用此类型参数。差不多

abstract class BaseContinuousSingleObjectiveFitnessFunction<T : BaseContinuousSingleObjectiveFitnessFunction<T>> {

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

    abstract fun construct(f: (List<Double>) -> Double): T

    // This is supposed to take a function that will be called on the result of invoke
    // and return an object derived from this one that has its invoke overriden to call
    // the new function on the result of the original one.
    fun modify(f: (Double) -> Double): T = construct { list -> f(this(x)) } 
}

open class XTimesA(val a: Double): BaseContinuousSingleObjectiveFitnessFunction<XTimesA>() {
    override operator fun invoke(x: List<Double>) = x.sumByDouble { a*it }

    override fun construct(f: (List<Double>) -> Double) = object : XTimesA(a) {
        override operator fun invoke(x: List<Double>) = f(x)
    }
}
抽象类BaseContinuousSingleObjectiveFitnessFunction{
//调用应该计算一些函数,比如f(x)=x^2+3x+5
抽象运算符调用(x:List):双精度
抽象趣味结构(f:(列表)->双精度):T
//这应该是一个函数,该函数将在调用的结果上被调用
//并返回从该对象派生的对象,该对象的调用被覆盖以调用
//新函数基于原始函数的结果。
fun modify(f:(Double)->Double:T=construct{list->f(this(x))}
}
开放类XTimesA(val a:Double):BaseContinuousSingleObjectiveFitnessFunction(){
重写运算符fun invoke(x:List)=x.sumByDouble{a*it}
覆盖有趣的构造(f:(List)->Double)=对象:XTimesA(a){
重写运算符fun invoke(x:List)=f(x)
}
}

然而,在这种特殊情况下,我认为它实际上没有意义,您的示例说明了原因:
f1.modify{it.pow(2)}
表示函数
x->x.sumByDouble{5*it}.pow(2)
,对于任何
a
,它都不是
x->x.sumByDouble{a*it}

但是如果其他类没有这个属性呢
XTimesA
有一个
a
,然后可能另一个类有一个
alpha
beta
,等等。基本上,如果属性不是真正可提升的,因为它们高度特定于实现它们的类,该怎么办?折衷方法是统一属性的名称。如果你不能统一它或者不想统一,那么我看不到一个优雅的解决方案。要做到这一点,我想Kotlin需要,谢谢!这个例子非常简单,因为在我的项目中使用catual函数是没有意义的,它要复杂得多。这些修改只是用于反转凸性或强制限制的更复杂修改的示例,如果示例不好,请原谅!
abstract class BaseContinuousSingleObjectiveFitnessFunction<T : BaseContinuousSingleObjectiveFitnessFunction<T>> {

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

    abstract fun construct(f: (List<Double>) -> Double): T

    // This is supposed to take a function that will be called on the result of invoke
    // and return an object derived from this one that has its invoke overriden to call
    // the new function on the result of the original one.
    fun modify(f: (Double) -> Double): T = construct { list -> f(this(x)) } 
}

open class XTimesA(val a: Double): BaseContinuousSingleObjectiveFitnessFunction<XTimesA>() {
    override operator fun invoke(x: List<Double>) = x.sumByDouble { a*it }

    override fun construct(f: (List<Double>) -> Double) = object : XTimesA(a) {
        override operator fun invoke(x: List<Double>) = f(x)
    }
}