Javaと異なり、Scalaではコンストラクタとクラス定義が一体化されている
class Person(name: String, age: Int) {
def greet(): String = s"Hi, my name is $name and I am $age years old."
}
Personnameとagegreet()インスタンス生成と呼び出し
val p = new Person("Alice", 30)
println(p.greet())
外からコンストラクタの引数にアクセスしたい場合、以下のようにすることで自動的にゲッターが生成される
class Person(val name: String, val kind: String)
参照:サンプルコード
case class User(id: Int, name: String)
case classを定義すると、以下のメソッドが自動生成される
apply:newを省略してインスタンス生成unapply:パターンマッチングで値を取り出すtoString:オブジェクトの文字列表現equals:オブジェクトの内容が等しいか判定hashCode:equalsとセットで使えるハッシュ値copy:一部フィールドだけを変更した新しいインスタンスを作れるval扱いになる(外部から読み取り可能に)newを省略してインスタンスを生成できるclassではデフォルトでは難解(オーバーライドすればよい)case classでは自動でわかりやすく生成される(例:Class(str=Hoge))case class User(name: String, age: Int)
val u = User("Alice", 20)
println(u.toString) // → User(Alice,20)
case classは構造比較User("Alice", 20) == User("Alice", 20) // → true
equalsが等しいならばhashCodeも等しくなるMapのキーやSetの要素に使う場合、重要val u = User("Alice", 20)
println(u.hashCode)
case class専用valが不変でも、copyで手軽に新しいバージョンが作れるval u1 = User("Alice", 20)
val u2 = u1.copy(age = 30) // nameはそのまま、ageだけ変更
参照:サンプルコード
classと異なり、newでインスタンス化する必要がないstaticのように、「どこからでも呼べる便利な機能」をまとめるのに使う参照:サンプルコード
classとobjectが同じ名前で同じファイルにある場合、そのobjectをコンパニオンオブジェクトというclassにapplyメソッドなどを追加したり、case classで自動生成されるメソッドをカスタマイズしたりできるclass:インスタンスを作る設計図object:クラスに関連する便利なメソッド・定数をまとめる場所参照:サンプルコード
newを省略してインスタンスを生成できるcase class User(id: Int, name: Stringを定義した時、以下のようなapplyメソッドが自動生成されている
def apply(name: String): User = new User(id, name)
user = User(1, "John")のように呼び出した時、実際にはUser.applyが呼び出されているcase class User(id: Int, name: Stringを定義した時、以下のようなunapplyメソッドが自動生成されている
def unapply(user: User): Option[(Int, String)] = Some((user.id, user.name))
case User(i, n)のようにパターンマッチングを行う時、実際にはUser.unapplyが呼び出されているUser(i, n)のi, nに値が展開される参照:サンプルコード