2017-09-24 39 views
4

我看到過幾個類似的問題,但沒有一個解釋爲什麼委託僅限於接口?爲什麼只有接口可以委託給kotlin?

大多數時間在實踐中我們有一些實際上根本沒有接口的東西,它是一個只實現一些功能或實現一個抽象類的類。

是否有任何根本性的限制,迫使它僅限於接口,或者我們可以期望kotlin在未來擁有無限制的授權?

如果我們想使用組合不繼承來擴展類的功能,這將特別有用。

class A {} 
class B(val a: A) : A by a {} 

回答

4

當您委派一個接口時,該類仍然實現該接口。所以爲了一致性,如果你可以委託一個類,它應該以同樣的方式工作。即

class A(x: Int) { 
    fun foo() = x 
} 

class B(val a: A) : A by a {} 

需要編譯成

class B(val a: A) : A { 
    override fun foo() = a.foo() 
} 

除了這不起作用:

  1. fooopen並且不能被重寫。

  2. 您需要調用A的構造函數。 class B(val a: A) : A(a.x)也不會幫助:x不是A的成員。

  3. equalshashCode怎麼樣?他們是否被委派?任何一個決定都會導致怪異的後果。

+0

1.所以它不應該試圖覆蓋它。應該自動委託可重寫的方法('open'或'abstact')。 2.所以'B'應該像往常一樣將構造參數傳遞給'A'。 3.因爲每個接口隱含地擴展了'Any',因此具有'equals','hashCode'和'toString',所以Kotlin作者必須爲接口委派做出這個決定。 – Jesse

+0

當然,這是一組可能的答案。但是,你不會「使用組合不繼承的方式擴展類的功能」;你有一個非常奇怪的組合和繼承組合,並且打開'A'中的方法而不改變它的行爲(例如,因爲你發現'C'需要重寫它)可以改變'B'的行爲。 –

相關問題