Search code examples
kotlinkotlin-interop

Platform Declaration Clash with Comparable


I'm getting a Platform Declaration Clash error from the compiler resulting from multiple default implementations of the Comparable interfaces (demonstrated below).

interface ClassA: Comparable<ClassA>
{
    val x: Int
        get

    override fun compareTo(other: ClassA): Int = this.x.compareTo(other.x)
}

interface ClassB: Comparable<ClassB>
{
    val y: String
        get

    override fun compareTo(other: ClassB): = this.y.compareTo(other.t)
}

data class ClassAB(val x: Int, val y: String): ClassA, ClassB
{
     ...
}

I understand why I'm getting this error; both default implementations of compareTo map to compareTo(Object) in Java. Thus, in the child, Kotlin doesn't know which one to use.

Is there a mechanism that will allow me to select the one to use, or, better yet, let me override compareTo(Object)? I've tried defining compareTo(Any), but that wasn't right. Another posting suggested using @JvmName, but the annotation doesn't apply here (per the compiler).

Any help would be greatly appreciated. Thanks!


Solution

  • Either you have to get rid of one of those comparables or you could use composition. It depends on you use case.

    Here is example for composition.

    data class ClassAB(val x: Int, val y: String): Comparable<ClassAB>
    {
        val classA: ClassA
        val classB: ClassB
    
        override fun compareTo(other: ClassAB): Int {
            // do compare
            classA.compareTo(other.classA)
            classB.compareTo(other.classB)
            throw UnsupportedOperationException("not implemented")
        }
    }