inheritance - Kotlin界面实现打破了 `equals`覆盖

标签 inheritance kotlin operator-overloading operators

我有以下类(class)作为其他一些类(class)的基础:

abstract class BaseFitness: Comparable<BaseFitness> {
    var valid: Boolean = false
    fun invalidate() { valid = false }
    abstract fun value(): Double
    abstract fun copy(): BaseFitness

    override operator fun equals(other: Any?): Boolean =
        if (other is BaseFitness)
            this.value() == other.value()
        else
            throw IllegalArgumentException("Can only compare to another class derived from BaseFitness.")

    override fun compareTo(other: BaseFitness): Int =
        this.value().minus(other.value())
            .let { if (it.isNaN()) 0.0 else it }
            .sign.toInt()

    @JvmName("compareToOperator")
    operator fun compareTo(other: Any?): Int =
        if (other is BaseFitness)
            this.compareTo(other)
        else
            throw IllegalArgumentException("Can only compare to another class derived from BaseFitness.")
}

现在,在本课中,我想实现基本的比较行为。

基本上,我希望能够做到:
  • if (fit1 == fit2) { /* do stuff */ }
  • if (fit1 > fit2) { /* do stuff */ }
  • if (fit1 < fit2) { /* do stuff */ }
  • myFitnessSequence.max()
  • equals()compareTo()运算符函数负责前3个项目。但是对于最后一项,我需要BaseFitness来实现Comparable。问题是,当我实现可比性并添加非运算符compareTo()方法时,equals()会因以下消息而中断:
    'operator' modifier is inapplicable on this function: must override ''equals()'' in Any
    

    我尝试做与compareTo()相同的操作,只是有2种实现equals(),一种标记为运算符,一种保留为方法,然后将@JvmName添加到其中一种,我得到了
    '@JvmName' annotation is not applicable to this declaration
    

    现在,我的选择基本上是选择保留和==运算符,但不实现Comparable或放弃==以使用可比性。

    最佳答案

    您无需使用equals关键字标记compareTooperator,这两个都已在各自的类型中定义为运算符。
    对于equalsAny将其定义为operator,并且compareTooperator Comparable中标记为interface
    因此,您要做的就是通过覆盖它们来提供它们的实现。
    Kotlin in Action

    Regarding the equals method

    The equals function is marked as override, because, unlike other conventions, the method implementing it is defined in the Any class (equality comparison is supported for all objects in Kotlin). That also explains why you don’t need to mark it as operator: the base method in Any is marked as such, and the operator modifier on a method applies also to all methods that implement or override it.

    Regarding the Comparable interface

    Kotlin supports the same Comparable interface. But the compareTo method defined in that interface can be called by convention, and uses of comparison operators ('<', '>', <=, and >=) are translated into calls of compareTo.

    关于inheritance - Kotlin界面实现打破了 `equals`覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60489771/

    相关文章:

    c++ - 调用基本构造函数而不直接调用

    ios - objective c 支持的继承

    javascript - 使用 Kotlin 创建简单的 Node 服务器

    spring - 即使使用 noarg 插件,也没有使用 Kotlin 的 JPA 实体的默认构造函数

    c++ - 程序进入无限循环 C++

    C++ 二维下标运算符

    c# - .Net继承和方法重载

    c++ - 层次结构中子类的对象的部分构造和破坏

    kotlin - kotlin 中这些 tailrec 函数有什么不同

    c++ - 修改 std::vector 函数(继承?)