Eu tenho uma interface com um método padrão, e duas classes que implementam esta interface. Uma das classes substitui o método padrão, e o outro não.
interface MyType {
fun giveHello(): String = "Hello!"
}
class Polite: MyType {
// Does not override giveHello()
}
class Rude: MyType {
override fun giveHello(): String = "I don't like you"
}
Eu ter acesso ao giveHello
método usando reflexão como esta:
val methodOfPolite = Polite::class.java.getDeclaredMethod("giveHello")
val methodOfRude = Rude::class.java.getDeclaredMethod("giveHello")
Há uma coisa estranha aqui. A classe educado não substitui o giveHello
método, mas o declaringClass
deste objeto método ainda aponta para Polite
.
Então, há uma maneira que eu possa verificar se a classe realmente se substituir o método interface padrão ou não?
Meu caso de uso é algo como isto (assumindo que podemos obter o comportamento que eu estou pedindo em uma propriedade chamada isOverriden
):
if (methodOfPolite.isOverriden) {
// do something
} else {
// do something else
}
Conforme descrito na KT-4779 , actualmente funções padrão KOTLIN não são implementados usando métodos efetivos padrão Java / JVM. As vidas de implementação padrão em um método estático em vez, e todas as classes que usam essa implementação padrão apenas chamar esse método estático. Isto é feito para assegurar funções padrão KOTLIN também trabalho na JVM alvo 1.6 que não tem ainda.
Portanto, o seu código de aproximadamente compila a este equivalente Java:
public interface MyType {
public String giveHello();
public static class MyTypeImpls {
public static String giveHello() { return "Hello!" }
}
}
public final class Polite implements MyType {
//does not override
public String giveHello() { return MyType.MyTypeImpls.giveHello() }
}
public final class Rude implements MyType {
//does override
override fun giveHello() { return "I don't like you" }
}
É por isso que java reflexão pensa ambas as classes substituir a função, ou seja, porque eles realmente fazem.
Você precisa usar Kotlin reflexão aqui, nomeadamente declaredMemberFunctions
e memberFunctions
:
fun overridesGiveHello(cls: KClass<Derp>) =
cls.memberFunctions.first { it.name == "giveHello" } in cls.declaredFunctions
println(overridesGiveHello(Polite::class)) //false
println(overridesGiveHello(Rude::class)) //true