Kotlin键入->任何->键入

时间:2019-10-05 04:38:47

标签: android generics kotlin

我想了解的是,如果在Kotlin中有一种方法可以做到这一点:

interface EnumClassX {
...
}

enum class EnumClassA: EnumClassX {
...
}
enum class EnumClassB: EnumClassX {
...
}
enum class EnumClassC: EnumClassX {
...
}

object Foo {
   fun bar(enumClassA: EnumClassA) {
       ...
   }
   fun bar(enumClassB: EnumClassB) {
       ...
   }
   fun bar(enumClassC: EnumClassC) {
       ...
   }
}

class Middle {
    fun callFooBar(enumClass: EnumClassX) {
        // What I have to do:
        when(enumClass){
            is EnumClassA -> {
                Foo.bar(enumClass) // Note I don't even have to say "enumClass as EnumClassA" b/c it is already inside an "is" block.
            }
            is EnumClassB -> {
                Foo.bar(enumClass)
            }
            is EnumClassC -> {
                Foo.bar(enumClass)
            }
        }

        // What I want to do:
        Foo.bar(enumClass) // IDE says "None of the following functions can be called without the arguments supplied." Compiler can't figure out which flavor of enumClass has been passed in to call the appropriate bar.
    }
}

可以轻松地通过其他简单的检查和切换来解决,如顶部示例中所示,但是否希望有一种方法可以使它相应地直接引导流量呢?我的意思是,总是使用具有单独的bar方法的三种类型之一来调用Middle.callFooBar,只是想知道Kotlin中是否有一种方法可以在不手动检查enumClass类型的情况下使其调用正确的方法。

谢谢! 斯科特

1 个答案:

答案 0 :(得分:1)

这是不可能的,因为您使用的是静态分派。
声明

  

// callFooBar可以用CustomObjectA,CustomObjectB或   CustomObjectC

实际上是不正确的。编译器看待它的方式,您的方法可以用任何类的实例来调用,而不仅仅是这三个类。

要使用动态调度,您将需要使用旧的良好继承。我知道,如今的继承并不酷,但您的情况恰恰是它的用途:

interface EnumClassX {
    fun bar()
}

class EnumClassA : EnumClassX {
    override fun bar() { }
}

class EnumClassB : EnumClassX {
    override fun bar() { }
}

class EnumClassC : EnumClassX {
    override fun bar() { }
}

从理论上讲,您的代码也应该使用密封类(不是枚举,它们是不同的):

sealed class EnumClassX {
    abstract fun bar()
}

class EnumClassA : EnumClassX() {
    override fun bar() { }
}

class EnumClassB : EnumClassX() {
    override fun bar() { }
}

class EnumClassC : EnumClassX() {
    override fun bar() { }
}

但事实并非如此。我的猜测仅仅是因为Kotlin团队不想进一步使编译器复杂化,但是也许我只是缺少了一些用例。随时问为什么在discuss.kotlinlang.org

上会这样