2016-03-07 14 views
9

Czy ktoś może mi wyjaśnić, jak porównać KClasse-y i interfejsy między sobą? I wiadomo, jak sprawdzić, że klasy lub interfejsy są równe, ale nie rozumiem, jak sprawdzić, że klasa jest nadklasą klasy B, itdJak porównać klasy i interfejsy?

interface IB {} 
interface IC : IB {} 

open class A {} 
open class B : A() {} 
open class C : B(), IC {} 

fun main(args: Array<String>) { 
    if (B::class == B::class) { println("B class is equal to B class") } 
    if (IB::class == IB::class) { println("IB interface is equal to IB interface") } 

    if (A::class ??? B::class) { println("A class is parent of B class") } 
    if (A::class ??? C::class) { println("A class is superclass of C class") } 

    if (C::class ??? IC) { println("C class is implement IC interface") } 
    if (IC ??? IB) { println("IC interface is implement IB interface") } 
} 
+1

Klutter Biblioteka posiada także rozszerzenia dla tych porównań 'Class' i' KClass', a także do '' KType' Type' i które mogą wystąpić podczas korzystania z refleksji Kotlin . https://github.com/kohesive/klutter/blob/master/reflect-core-jdk6/src/main/kotlin/uy/klutter/reflect/Types.kt i więcej w https://github.com/kohesive/ klutter/blob/master/reflect-full-jdk6/src/main/kotlin/uy/klutter/reflect/full/Types.kt –

Odpowiedz

8

Kotlin odbicie nie posiada API do pobierania informacji o KClass hierarchia, więc jedynym sposobem, aby sprawdzić, czy jeden KClass jest nadklasą lub podklasą innej KClass jest porównanie odpowiednich klas java:

interface IB {} 
interface IC : IB {} 

open class A {} 
open class B : A() {} 
open class C : B(), IC {} 

fun main(args: Array<String>) { 
    if (B::class == B::class) { println("B class is equal to B class") } 
    if (IB::class == IB::class) { println("IB interface is equal to IB interface") } 

    if (A::class.java.isAssignableFrom(B::class.java)) { println("A class is parent of B class") } 
    if (A::class.java.isAssignableFrom(C::class.java)) { println("A class is superclass of C class") } 

    if (IC::class.java.isAssignableFrom(C::class.java)) { println("C class is implement IC interface") } 
    if (IB::class.java.isAssignableFrom(IC::class.java)) { println("IC interface is implement IB interface") } 
} 

UPDATE: można również zdefiniować dwie funkcje przedłużenia, które MAK e ten rodzaj kontroli nieco ładniejsze:

inline fun <reified L : Any, reified R : Any> isSubClassOf(): Boolean { 
    return R::class.java.isAssignableFrom(L::class.java) 
} 

inline fun <reified L : Any, reified R : Any> isSuperClassOf(): Boolean { 
    return L::class.java.isAssignableFrom(R::class.java) 
} 

fun main(args: Array<String>) { 
    if (isSubClassOf<B, B>()) { println("B class is equal to B class") } 
    if (isSubClassOf<IB, IB>()) { println("IB interface is equal to IB interface") } 

    if (isSuperClassOf<A, B>()) { println("A class is parent of B class") } 
    if (isSuperClassOf<A, C>()) { println("A class is superclass of C class") } 

    if (isSubClassOf<C, IC>()) { println("C class is implement IC interface") } 
    if (isSubClassOf<IC, IB>()) { println("IC interface is implement IB interface") } 
} 
+1

wow, spodziewałbym się, że operator 'compareTo 'zostanie przeciążony dla tego – voddan

+0

@voddan którego nie możesz zdefiniuj operator 'compareTo' dla częściowo uporządkowanych zbiorów –

+1

@ VladimirMironov Myślę, że @voddan ma na myśli coś takiego [https://gist.github.com/maxd/8f967002343865dd40a7). Jak widzisz, możesz przesłonić 'compareTo' i użyć' <', '> ',' <=', '> = 'operatory dla klas porównania (na przykład taka składnia w Ruby). Mam nadzieję, że kotlin.reflect będzie miał coś takiego w przyszłości. –