2016-02-26 178 views
6

我试图创建少数类的层次结构,每个类重写它的父类的内部类中的一些行为(特别是迭代器,但没关系)。基本上,它看起来像这样:Kotlin内部类继承

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

编译器拒绝与此代码工作,在预计将InnerClass类型参数时ChildInnerClass从它继承。然而,添加参数这样后:

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

,我是在做科特林做错了事,或者是它只是一个语言限制,我是不知道的呢?

回答

5

编译器不期待InnerClass上的类型参数,但在SuperClass.InnerClassSuperClass上。这是一个已知问题:Capture generics in inner classes : 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") 
     } 
    } 
} 

Hadoop Context type parameters in Kotlin见一个类似的例子和答案。

+0

捎带一个问题,因为我是Kotlin的新手:我试图让我的头在这个问题上,答案上的代码不会为我编译。我不得不在'InnerClass'上添加类型参数,所以它最终成为'内部类ChildInnerClass:SuperClass .InnerClass ()',我认为这是链接的答案建议做...我错过了什么吗? – Augusto

+0

只有在用类型参数('protected open inner class InnerClass ')定义它时,你才需要在'InnerClass'上指定类型参数。在这段代码中'InnerClass'不需要类型参数,而是从它的父类中使用T, SuperClass' – EiG

+0

@Augusto如果答案上的代码没有为你编译,那么我猜你已经对'InnerClass'等进行了一些修改。为了清晰起见,我已经更新了代码中的答案,包括'SuperClass'声明。您应该可以将示例复制并粘贴到新的Kotlin文件中,并且应该可以毫无问题地进行编译。请让我们知道,如果它不适合你。 – mfulton26