harold_admin:
私は、このインタフェースを実装するデフォルトの方法とのインタフェース、および2つのクラスを持っています。クラスの一つは、デフォルトのメソッドをオーバーライドし、他にはありません。
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"
}
私はへのアクセスを得るgiveHello
。このような反射を利用する方法を:
val methodOfPolite = Polite::class.java.getDeclaredMethod("giveHello")
val methodOfRude = Rude::class.java.getDeclaredMethod("giveHello")
ここで1奇妙なことがあります。丁寧なクラスがオーバーライドしないgiveHello
方法を、しかし、declaringClass
この方法でオブジェクトのは、まだを指しますPolite
。
だから私は、クラスが実際にデフォルトのインターフェイスメソッドをオーバーライドしたりしませんでしたかどうかを確認することができます方法はありますか?
私のユースケースは、(私たちは、私が呼ばれるプロパティにするために求めている動作を得ることができると仮定すると、このようになりますisOverriden
):
if (methodOfPolite.isOverriden) {
// do something
} else {
// do something else
}
トッド・シーウェル:
記載のようにKT-4779、現在Kotlinのデフォルト機能は、実際のJava / JVMのデフォルトの方法を使用して実装されていません。代わりに、静的メソッドのデフォルトの実装の生活、およびそのデフォルトの実装を使用して、すべてのクラスは、ちょうどその静的メソッドを呼び出します。これはまた、それらをまだ持っていない1.6 JVMターゲットの作業をKotlinのデフォルトの機能を確保するために行われます。
あなたのコードは、おおよそこの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" }
}
Javaのリフレクションは、両方のクラス、すなわち、彼らが実際に行うための機能を、上書き思う理由です。
あなたは、特に、ここではKotlin反射を使用する必要があるdeclaredMemberFunctions
と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