2017-05-04 119 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>() { /* ... */ }