Deal with list of supertype Items according to their subtypes

I have a List<ParentType> that contains items from a hodgepodge of types that inherit from ParentType, which I’ll call ChildType1, ChildType2, etc.

Now I need to iterate over this list and call a method doStuff, which is defined differently in each of the various ChildType classes. The simple myList.forEach {it.doStuff()} doesn’t work because the items coming out of myList are treated as if they are ParentType instead of their respective ChildTypes.

So what I have now is

myList.forEach { 
    when(it) {
        is ChildType1 -> it.doStuff()
        is ChildType2 -> it.doStuff()
        is ChildType3 -> it.doStuff()
        // and a bunch more

The when & smart casts do the job, but is this really the best solution? I’d like to think there was a way to do this without a separate line for each of the multitude of ChildTypes, but I can’t seem to figure one out.

Thanks in advance for any insight.

1 Like

Just define abstract doStuff in your ParentType and let polymorphism do the job with the simple option you mentioned:

abstract class ParentType { // or even better use interface if applicable in your case
    abstract fun doStuff()

class ChildType1 : ParentType() {
    override fun doStuff() = println("called from 1")

class ChildType2 : ParentType() {
    override fun doStuff() = println("this is 2")

class ChildType3 : ParentType() {
    override fun doStuff() = println("and that's 3")

fun main() {
    val myList: List<ParentType> = listOf(ChildType1(), ChildType2(), ChildType3())
    myList.forEach { it.doStuff() }

That worked perfectly. Thank you.

1 Like