時にはあるクラスをわずかに修正しただけのオブジェクトをそれのための新しいサブクラスを明示的に宣言せずに、作成する必要があります。Javaでは 無名内部クラス でこの事例を処理します。 Kotlinではたった オブジェクト式 と オブジェクトの宣言 だけでこの概念を一般化します。
オブジェクト式
いくつかの型(1つでも複数でも)から継承する無名クラスのオブジェクトを作成するには、このようにします:
override fun mouseEntered(e: MouseEvent) {
// ...
}
})
スーパータイプがコンストラクタを持っている場合は、適切なコンストラクタのパラメータが渡されなければなりません。多くのスーパータイプは、コロンの後にコンマ区切りのリストとして指定することができます:
interface B {...}
val ab: A = object : A(1), B {
override val y = 15
}
万が一、自明でないスーパータイプの「オブジェクトのみ」が必要な場合は、単純に次のように言うことができます:
ただ、Javaの無名内部クラスのように、内包するスコープからオブジェクト式のコードが変数にアクセスすることができます。(Javaのとは違って、これは final の変数に限定されるものではありません。)
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
clickCount++
}
override fun mouseEntered(e: MouseEvent) {
enterCount++
}
})
// ...
}
オブジェクトの宣言
シングルトンは非常に便利なパターンであり、Kotlin(Scalaの後です)は、シングルトンを容易に宣言で切るようにしました:
val allDataProviders: Collection<DataProvider>
get() = // ...
}
?これは、オブジェクトの宣言と呼ばれ、それは常に object キーワードの後に名前を持ちます。ちょうど変数宣言と同じように、オブジェクトの宣言は式ではなく、代入文の右側に使用することはできません。
オブジェクトを参照するために、その名前を直接使用します。
override fun mouseEntered(e: MouseEvent) {
// ...
}
}
注:オブジェクト宣言はローカルにすることはできません(つまり、関数内で直接ネストしてください)。ただし、他のオブジェクト宣言または非内部クラスにネストすることもできます。
コンパニオンオブジェクト (Companion Objects)
クラス内のオブジェクトの宣言は、 companion キーワードでマークすることができます。
コンパニオンオブジェクトのメンバーは修飾子として単にクラス名を使用して呼び出すことができます:
val x = MyClass.Companion
コンパニオンオブジェクトのメンバは、他の言語のスタティックメンバのように見えますが、実行時にはそれらはまだ実際のオブジェクトのインスタンスメンバであり、たとえばインターフェイスを実装できます:
class MyClass {
companion object : Factory<MyClass> {
override fun create(): MyClass = MyClass()
}
}
しかしながら、JVM上では、 @JvmStatic アノテーションを使用すると、コンパニオンオブジェクトのメンバを実際の静的メソッドやフィールドとして生成することができます。詳細については、Javaの相互運用性のセクションを参照してください。
オブジェクト式と宣言の間の意味の違い
オブジェクト式とオブジェクトの宣言の間には、ある重要な意味上の違いがあります: