EiG
EiG

Reputation: 93

Inner classes Inheritance in Kotlin

I'm trying to create a hierarchy of few classes, each one overriding some behavior in inner classes of it's parent (Specifically iterators, but it does not matter). Basically, it looks like this:

open class SuperClass<T>{
    protected open inner class InnerClass{
        fun someLogic(){
            println("some logic happened")
        }

        open fun someOverridableLogic(){
            println("some logic happened")
        }
    }
}

class ChildClass<T> : SuperClass<T>(){
    protected inner class ChildInnerClass:InnerClass{
        override fun someOverridableLogic(){
            super.someOverridableLogic()
            println("some OTHER logic happened")
        }
    }
}

Compiler refuses to work with this code, expecting type parameter on InnerClass when ChildInnerClass inherits from it. However, after adding parameter like this:

protected inner class ChildInnerClass:InnerClass<T>

compiler suddenly does not expect any type parameters!

Java equivalent of this compiles and executes as expected, without type parameters:

public class SuperClass<T> {
    protected class InnerClass{
        public void someLogic(){
            System.out.println("some logic happened");
        }

        public void someOverridableLogic(){
            System.out.println("some logic happened");
        }
    }
}


public class ChildClass<T> extends SuperClass<T>{
    protected class ChildInnerClass extends InnerClass{
        @Override
        public void someOverridableLogic() {
            super.someOverridableLogic();
            System.out.println("some OTHER logic happened");
        }
    }
}

So, am i doing something wrong in Kotlin, or is it simply a language restriction i wasn't aware about?

Upvotes: 9

Views: 5142

Answers (1)

mfulton26
mfulton26

Reputation: 31214

The compiler is not expecting a type argument on InnerClass but on SuperClass in SuperClass.InnerClass. This is a known issue: Capture generics in inner classes : KT-9208.

For now you can do the following:

open class SuperClass<T> {
    protected open inner class InnerClass {
        fun someLogic() {
            println("some logic happened")
        }

        open fun someOverridableLogic() {
            println("some logic happened")
        }
    }
}

class ChildClass<T> : SuperClass<T>() {
    protected inner class ChildInnerClass : SuperClass<T>.InnerClass() {
        override fun someOverridableLogic() {
            super.someOverridableLogic()
            println("some OTHER logic happened")
        }
    }
}

See also Hadoop Context type parameters in Kotlin for a similar example and answer.

Upvotes: 7

Related Questions