ちゃんと実装してやればよいのです! class Name(val value: String) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false other as Name if (value != other.value) return false return true } override fun hashCode(): Int = value.hashCode() override fun toString(): String = "Name(value='$value')" }
ちゃんと実装してやればよいのです! class Name(val value: String) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false other as Name if (value != other.value) return false return true } override fun hashCode(): Int = value.hashCode() override fun toString(): String = "Name(value='$value')" } ・・・
地味に便利なcomponentNメソッド data class FullName(val firstName: String, val lastName: String) val nagasawa = FullName("太郎", "長澤") val (first, last) = nagasawa first //=> 太郎 last //=> 長澤
地味に便利なcomponentNメソッド data class FullName(val firstName: String, val lastName: String) val nagasawa = FullName("太郎", "長澤") val (first, last) = nagasawa first //=> 太郎 last //=> 長澤 分解宣言
地味に便利なcomponentNメソッド data class FullName(val firstName: String, val lastName: String) { operator fun component1(): String = firstName operator fun component2(): String = lastName } val nagasawa = FullName("太郎", "長澤") val (first, last) = nagasawa first //=> 太郎 last //=> 長澤 データクラスがこのようなメソッド実装を自動生成する
[ver1.1より前] クラスを継承できなかった sealed class Exp { class Number(val value: Int): Exp() class Addition(val x: Exp, val y: Exp): Exp() } val exp: Exp = Addition(Number(1), Number(2)) val sum: Number = eval(exp) sum //=> [email protected]
[ver1.1より前] クラスを継承できなかった sealed class Exp { class Number(val value: Int): Exp() class Addition(val x: Exp, val y: Exp): Exp() } val exp: Exp = Addition(Number(1), Number(2)) val sum: Number = eval(exp) sum //=> [email protected] dataを付けるとコンパイルエラーとなっていた
[ver1.1以降] クラスの継承OK sealed class Exp { data class Number(val value: Int): Exp() data class Addition(val x: Exp, val y: Exp): Exp() } val exp: Exp = Addition(Number(1), Number(2)) val sum: Number = eval(exp) sum //=> Number(value=3)
データクラスを継承するのはNG open data class Name(val value: String) data class NameWithRuby(val value: String, val ruby: String): Name(value) ● 実装の継承はあまりよろしくない ● できたとしてcopyやcomponentNにおかし なことが起こるか大きな制限がかかる ● all-openコンパイラプラグインで継承可能。 ただしサブクラスはデータクラスにできない。
データクラスを継承したくなったら data class Name(val value: String) data class NameWithRuby(val value: String, val ruby: String) { fun toName(): Name = Name(value) } interface StringWrapper { val value: String fun component1(): String } data class Name(override val value: String): StringWrapper data class NameWithRuby(override val value: String, val ruby: String): StringWrapper このどちらか、 または両方で対処
対象オブジェクト thisかitか 対象オブジェクト 戻り値 run this 指定できる let it 指定できる apply this 対象オブジェクト also it 対象オブジェクト ● itの方を使っておけば無難 → 命名できる、文脈を維持 ● thisの方を使った方が楽な場面はある → ただし、ネストは避けること