2017-09-24 12 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)は役に立ちません。xAのメンバーではありません。

  3. equalshashCodeについて:委任されていますか?どちらの決定でも奇妙な結果につながる。

+0

1.それを上書きしようとするべきではありません。オーバーライド可能なメソッド( 'open'または' abstact')のみが自動的に委譲されるべきです。 2.したがって、 'B'はコンストラクタパラメータを通常どおり' A'まで渡す必要があります。 3.すべてのインタフェースが暗黙的に 'Any'を拡張し、' equals'、 'hashCode'および' toString'を持っているので、Kotlinの作者はすでにインタフェース委譲のためにこの決定を下さなければなりませんでした。 – Jesse

+0

確かに、それは可能な答えのセットです。しかし、「継承ではないコンポジションを使用してクラスの機能を拡張する」ことはできません。あなたは構図と継承のかなり奇妙な組み合わせを持っていて、その挙動を変えずに 'A'でメソッドを作ることができます(例えば、' C'がそれをオーバーライドする必要があると考えたため) 'B'の振る舞いを変えることができます。 –

関連する問題