たとえば、両方の関数を使用できるように、拡張example()
する型の関数を作成したいと考えています。Child
Parent
Child.example()
Parent.example()
これを行う最初の「明白な」方法は、のコンパニオンオブジェクトをParent
使用することexample()
ですが、これはを許可しませんChild
。
私が試した2番目の方法は、拡張関数をParent.Companion
で定義することでした。これは、コンパニオンオブジェクトを定義することを強いられるため、不便です。また、も許可さexample()
れていませんChild
。
誰か私がこれを行う方法を知っていますか?
あなたが求めているものは存在しません、あなたは尋ねているように見えます:
子孫のクラス参照からスーパークラスのコンパニオンオブジェクトメソッドを参照できますか
または多分あなたは尋ねています:
子孫の参照からスーパークラスの静的メンバーを参照できますか?
両方の答えはノーです。これが許可されないのはKotlinの設計によるものであり、意識的な決定であり、意図的なものでした。この決定を変更する場合は、YouTrackで問題を報告する必要があります。Javaのプログラマーは、静的メソッドの継承とオーバーライド、およびある参照から別の参照から呼び出されたときの動作と、動的ではなく静的に解決される方法に非常に混乱していました。Java 8チームは、静的メソッドをインターフェースに追加するときに混乱が生じる可能性があることを認識しているため、インターフェース参照によってのみ呼び出されるようにするKotlinのアプローチを採用しました。このタイプの悪夢を回避するために、Kotlinチームはそれを禁止しました。彼らがJavaの他の多くの紛らわしい側面を拒否したのと同じように。
他の回答(@voddanなど)では、コンパニオンオブジェクトを使用して構文を呼び出すのと同じ感覚が得られる回避策が提供されますが、質問で次のように述べられていても、コンパニオンオブジェクトを避けたいと言ってコメントでそれらを拒否します。それらを使用しようとしています。したがって、それらを使用したくない場合、答えは単に「いいえ」であり、実行できません。
コンパニオンオブジェクトを取り除くには、拡張関数を「静的」な方法で呼び出すことができるかについて説明しますか?...それはまだ許可されていないのでがっかりするでしょう。
コンパニオンオブジェクトに戻って(申し訳ありませんが、ここでは栄光への1つの道です)、子のメソッドを手動で親に委任することもできます。
open class Parent {
companion object { // required, sorry, no way around it!
fun foo() = /* some cool logic here */
}
}
class Child: Parent() {
companion object { // required, sorry, no way around it!
fun foo() = Parent.foo()
}
}
または拡張機能として:
open class Parent {
companion object {} // required, sorry, no way around it!
}
class Child: Parent() {
companion object {} // required, sorry, no way around it!
}
fun Parent.Companion.foo() = /* some cool logic here */
fun Child.Companion.foo() = Parent.foo()
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加