2017-05-04 55 views
4

例如在Java中我可以这样写:交叉引用参数

public abstract class Element<S extends Snapshot> { ... } 
public abstract class Snapshot<E extends Element> { ... } 

,然后某处,扩展这一类:

public class SnapshotImpl extends Snapshot<ElementImpl> { ... } 
public class ElementImpl extends Element<SnapshotImpl> { ... } 

但是,当我试图实现科特林同一类层次结构:

abstract class Element<S : Snapshot> 
abstract class Snapshot<E : Element> 

我得到了下面的编译错误:

Error:(6, 28) Kotlin: One type argument expected for class Snapshot<E> defined in model Error:(6, 25) Kotlin: One type argument expected for class Element<S> defined in model

是否有任何方法可以在Kotlin中重现相同类型的参数限制?

回答

10

Kotlin没有原始类型,你不能只删除类型参数。类似原始类型

一种选择是使用star projections

abstract class Element<S : Snapshot<*>> { /* ... */ } 
abstract class Snapshot<E : Element<*>> { /* ... */ } 

但你将无法正常使用的类型参数一般成员的工作。


另一种选择是引入相互制约这样的:

abstract class Element<E : Element<E, S>, S : Snapshot<S, E>>() { /* ... */ } 
abstract class Snapshot<S : Snapshot<S, E>, E : Element<E, S>>() { /* ... */ } 

根据这个定义,你可以肯定的是,如果你定义SomeSnapshot: Snapshot<SomeSnapshot, SomeElement>,类型SomeElement意识到SomeSnapshot,因为它被限制为从Element<SomeElement, SomeSnapshot>派生。

则实现将是:

class SomeElement : Element<SomeElement, SomeSnapshot>() { /* ... */ } 
class SomeSnapshot : Snapshot<SomeSnapshot, SomeElement>() { /* ... */ }