What I want is this:
interface base {
abstract static fun foo()
}
class impl : base {
override static fun foo()
}
Normally, Kotlin solves problems using companion objects rather than static functions. But an interface can't define a requirement for a companion object with function. So how can I accomplish this? The code that uses this would look like
fun <T : base> bar() {
T.foo()
}
Any other way to get this behavior? Namely, that I can execute a function of a derivative of T
, without knowing the specific type, and not assuming the derivative has a default constructor?
Edit
I was able to get this to do what I want by using value parameters of types that can be set on the companion objects of the classes I want to work with. An illustrative example of what I want to use this technique for.
import kotlin.reflect.full.*
interface DynamicBuilder {
fun build(sides: Int): Shape?
}
interface Shape {
companion object : DynamicBuilder {
override fun build(sides: Int) = null
}
}
abstract class Shape2D : Shape {
companion object : DynamicBuilder {
override fun build(sides: Int) = if(sides > 0) Square() else Circle()
}
}
abstract class Shape3D : Shape {
companion object : DynamicBuilder {
override fun build(sides: Int) = if(sides > 0) Cube() else Sphere()
}
}
class Square : Shape2D()
class Circle : Shape2D()
class Sphere : Shape3D()
class Cube : Shape3D()
fun Build(sides: Int, builder: DynamicBuilder): Shape? {
return builder.build(sides)
}
inline fun <reified T : Shape> Build(sides: Int): Shape? {
return Build(sides, T::class.companionObjectInstance as DynamicBuilder)
}
fun main() {
println(Build(0, Shape2D))
println(Build(4, Shape2D))
println(Build<Shape3D>(0))
println(Build<Shape3D>(6))
}
The goal is that I can create a new entire class of Shape
, and have all the logic related to how it builds the concrete object contained in that file, rather than having some monolithic shared switch statement.