I have a polymorphic class tree. I want to enumera...
# getting-started
t
I have a polymorphic class tree. I want to enumerate a list of leaf classes, and evaluate each one with an argument and let each one tell me how suited it is for that context. The sorting and selection is straightforward to me. It's how to get abstract class side methods and a list of class instances that is confounding me.
Copy code
listOf<DragGesture>(DragCyclePositionGesture.class, DragMoveGesture.class, DragBeginGesture.class, DragEndGesture.class)
is not legal. Number one, there needs to be way a way to make the template not be instances of DragGesture, but rather subtypes of DragGesture? Is that even specifiable? And the compiler isn't happy after the first .class either, i start getting all kinds of red after that. Am I supposed to use companions in this case? I'm not even sure how companions fit in the scheme of inheritance. 😕
j
First things first, Kotlin's way of referring to classes is
MyClass::class
(not
.class
). Now that being said, if you want to use inheritance so that the classes can tell you something polymorphically (not instances of those classes), then using companion objects seems appropriate because they can implement interfaces, unlike
KClass
or
Class
t
The solution I came up with looks like:
Copy code
val candidates = listOf(
   Pair(DragCyclePositionGesture::proximity, ::DragCyclePositionGesture),
   Pair(DragMoveGesture::proximity, ::DragMoveGesture),
   Pair(DragBeginGesture::proximity, ::DragBeginGesture),
   Pair(DragEndGesture::proximity, ::DragEndGesture)
)
val filtered = candidates.filter { it.first(this, event).abs <= tolerance }
return filtered.minByOrNull { it.first(this, event).abs }?.let { (_, constructor) ->
   val gesture = constructor()
   gesture.loadFrom(this)
   gesture
}
The part I'm not too hip on is the pairs of companion::function and constructor reference.
I would have rather seen
xxx.proximity(this, event)
in the filter and minBy blocks
j
Instead of a pair like this you could use an interface like
GestureFactory<T : DragGesture>
and make the companion objects of each class implement it. It would define the proximity function and factory function in a nicer way I guess
So you would just have a list of companion objects instead of a list of pairs
t
how does one make a list of companion objects?
j
Just use
listOf(DragMoveGesture, DragBeginGesture)
(etc.)