Kotlin中的内部类继承

9

我正在尝试创建几个类的层次结构,每个类都覆盖其父类内部类(具体来说是迭代器)的某些行为。基本上,它看起来像这样:

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")
        }
    }
}

编译器拒绝处理此代码,因为 ChildInnerClass 继承 InnerClass 时需要类型参数。然而,只要像这样添加参数:

protected inner class ChildInnerClass:InnerClass<T>

编译器突然不再需要任何类型参数!

Java的等效代码可以正常编译和执行,而且不需要类型参数:

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");
        }
    }
}

那么,我在 Kotlin 中做错了什么,还是有一些语言限制我不知道的吗?
1个回答

7
编译器不希望在 "InnerClass" 上使用类型参数,而是在 "SuperClass" 上使用类型参数,即在 "SuperClass.InnerClass" 中。这是一个已知的问题:捕获内部类中的泛型:KT-9208
目前,您可以执行以下操作:
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")
        }
    }
}

请参考使用Kotlin中的Hadoop Context类型参数,了解类似的示例和答案。


作为 Kotlin 的新手,我想请教一个问题:我正在尝试理解这个问题,并且答案中的代码对我来说无法编译。我不得不在 InnerClass 上添加类型参数,所以最终变成了 inner class ChildInnerClass : SuperClass<T>.InnerClass<T>(),我认为这就是链接答案建议做的事情... 我有什么遗漏吗? - Augusto
只有在您使用类型参数定义了 protected open inner class InnerClass<T> 时,才需要在 InnerClass 上指定类型参数。在此代码中,InnerClass 不需要类型参数,而是从其父类 SuperClass 中使用 T。 - EiG
@Augusto 如果答案中的代码无法编译,那么我猜测您对 InnerClass 等进行了一些更改。为了清晰起见,我已经更新了答案中的代码,包括 SuperClass 声明。您应该能够将示例复制并粘贴到新的 Kotlin 文件中,而且不应该出现任何问题。如果有问题,请告诉我们。 - mfulton26
我真是太傻了!在玩代码时,不知道什么时候在SuperClass.InnerClass加上了<T>。谢谢你澄清了这一点!!! - Augusto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接