Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inner classes Inheritance in Kotlin

Tags:

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?

like image 632
EiG Avatar asked Feb 26 '16 12:02

EiG


People also ask

Are inner classes inheritance?

Inner classesA inner class declared in the same outer class (or in its descendant) can inherit another inner class.

What is an inner class in Kotlin?

Kotlin Inner class Inner class is a class which is created inside another class with keyword inner. In other words, we can say that a nested class which is marked as "inner" is called inner class. Inner class cannot be declared inside interfaces or non-inner nested classes. class outerClass{ //outer class code.

How do I inherit a class at Kotlin?

Everything in Kotlin is by default final, hence, we need to use the keyword open in front of the class declaration to make it inheritable for other classes. Kotlin uses operator ":" to inherit a class.

What is an inner class and how it is different from an inheritance?

An inner class has nothing to do with a subclass. You use inheritance if you like to extend a parent class or where a "is a" relation exists. This is not necessarily the case for inner classes. They can (for example) be used as small helper classes, like in Map implementations, there the Entry class is nested.


1 Answers

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.

like image 83
mfulton26 Avatar answered Sep 24 '22 15:09

mfulton26