Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare classes and interfaces?

Can anybody explain me how to compare KClasses and interfaces among themselves? I know how to check if classes or interfaces are equal but I don't understand how to check if A class is a superclass of B class, etc.

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 implements IC interface") }
  if (IC ??? IB) { println("IC interface implements IB interface") }
}
like image 870
Maxim Avatar asked Mar 07 '16 18:03

Maxim


People also ask

How do you differentiate between a class and an interface?

Differences between a Class and an Interface:A class can be instantiated i.e, objects of a class can be created. An Interface cannot be instantiated i.e, objects cannot be created. Classes does not support multiple inheritance. Interface supports multiple inheritance.

How will you compare abstract classes and interfaces?

The key technical differences between an abstract class and an interface are: Abstract classes can have constants, members, method stubs (methods without a body) and defined methods, whereas interfaces can only have constants and methods stubs.

What are the similarities between classes and interfaces?

It is similar to class. It is a collection of abstract methods. A class implements an interface, thereby inheriting the abstract methods of the interface. Along with abstract methods, an interface may also contain constants, default methods, static methods, and nested types.

Why are interfaces better than classes?

An interface is better than a abstract class when you want multiple classes to implement that interface and when you don't have to inherit default behavior. Save this answer.


1 Answers

Kotlin reflection doesn't have an API for retrieving information about KClass hierarchy, so the only way to check if one KClass is superclass or subclass of another KClass is to compare corresponding java classes:

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 implements IC interface") }
  if (IB::class.java.isAssignableFrom(IC::class.java)) { println("IC interface implements IB interface") }
}

UPDATE: You can also define two extension functions that will make this kind of checks a bit nicer:

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 implements IC interface") }
  if (isSubClassOf<IC, IB>()) { println("IC interface implements IB interface") }
}
like image 89
Vladimir Mironov Avatar answered Sep 30 '22 06:09

Vladimir Mironov