事の発端
師匠に突っ込まれたので。
まだまだ、思考が浅かったです。
データクラスとは?
データクラスとは、Kotlin特有の仕様で、データを保持するだけのクラスはdataマークをつけることで定義されます。
データクラスとして成り立たせるには、
- プライマリコンストラクタに引数を一つは持たせること。
- val or var でイミュータブルか否かを明示すること
- 抽象クラス、openクラス,シールドクラス、インナークラスであってはならない
が必要です。
Javaでは、フレームワークに依存していない無添加なオブジェクトによって、(いわゆるPOJO)データを保持するだけのクラスは作れますが、かなりボイラープレート多いです。
普通のクラスとの違い
上記3つの縛りはあるものの、確かに違いは何かと言われるとちゃんと考えていなかった。
恐らく、dataマークを付与することでデータを保持するのに特化した仕様になるのだろうが、何が違うのか?・・・
結論を先に言うと、「データを扱うのに便利なメソッドが自動で実装される」です。
どんなメソッド?
元々全クラスの継承元、Anyクラスが持つ
- toString()
- hashCode()
- equals()
に加え
- copy():コピーできる
- componentN():N番目のプロパティを返す
が実装されます。
また、同じメソッドでも仕様に違いが生じます。
class Hoge() {}
data class Piyo(val fuga: String)
class Main() {
val hoge = Hoge()
val hoge2 = Hoge()
print(hoge.toString()) // Hoge@12345 <- ハッシュ値を含んだこんな感じのが出力される
print(hoge.equal(hoge2)) // false <- 当然別インスタンスなので、異なるという判定
val piyo = Piyo("Kotlin")
val piyo2 = Piyo("Kotlin")
print(piyo.toString) // Piyo(fuga = Kotlin) <- データのプロパティを含んだものが出力される
print(piyo.conponent1) // Kotlin <- 一番目のプロパティが出力される
print(piyo.equals(Piyo2)) // true <- 別インスタンスであるが、プロパティが同じなので同一という判定
}
それと、hashCode()に関しては、データクラスの場合プロパティに基づいたハッシュ値ですが、普通のクラスはインスタンスに基づくものです。
この点からもデータを扱うという目的に特化していることがわかりますね。
終わりに
データクラスは、魔法のクラスから少し理論的に踏み込めたので、書いていて楽しかった。
参考