【Scala】Scala ~ 基本編 / クラス ~

■ はじめに

https://dk521123.hatenablog.com/entry/2023/03/10/193805
https://dk521123.hatenablog.com/entry/2023/03/12/184331

の続き。

今回は、クラス周辺について扱う。

試す環境
https://scastie.scala-lang.org/CEpZy3v4Taa0MCStp3LCYg

目次

【1】クラス
 1)構文
 2)アクセス権限
【2】コンストラクタ
 1)基本コンストラクタ (デフォルトコンストラクタ)
 2)補助コンストラクタ
【3】継承
 1)構文
 2)継承させない - final
【4】その他クラス
 1)抽象クラス
 2)ケースクラス - case class
 3)オブジェクト - object
 4)コンパニオンオブジェクト

【1】クラス

https://docs.scala-lang.org/ja/tour/classes.html
https://scala-text.github.io/scala_text/class.html

サンプル

// クラス定義
class DemoClass(val id: Int, var name: String,val age: Int = 30) {
  val HELLO = "Hello"
  var greeting: String = "Hi"

  // メソッド定義(def)
  def sayHello(): String = {
    s"Hello, ${this.name}"
  }
}

// 呼び出し側
val obj = new DemoClass(1, "Mike")
// id=1, name=Mike, age=30
println(s"id=${obj.id}, name=${obj.name}, age=${obj.age}")
println(obj.sayHello())

1)構文

class <クラス名> '(' (<引数名1> : <引数型1>, <引数名2>: <引数型2> ...)? ')' {
  (<フィールド定義> | <メソッド定義> )*
}

2)アクセス権限

* Javaと比べてパッケージやクラスレベルでの詳細なアクセス権限が設定できる
名前 キーワード 説明
公開(public) なし どこからでも参照可能
非公開 private それを定義しているクラス、オブジェクト内からのみ参照可能
限定公開 protected それを定義しているサブクラスからのみ参照可能
スコープ指定非公開 private[scope] scopeはアクセス可能
スコープ指定限定公開 protected[scope] 対象のサブクラスとscopeはアクセス可能

【2】コンストラク

* Scalaには、以下がある
1)基本コンストラクタ (デフォルトコンストラクタ)
2)補助コンストラクタ

1)基本コンストラクタ (デフォルトコンストラクタ)

// コンストラクタで値を設定する場合は、クラス名の後ろの()内にフィールドを定義
class ClassExample(val x: Int, var y: Int, z: Int = 0) {

https://qiita.com/takudo/items/8731612acbe7eae83183

2)補助コンストラク

* 引数の異なる複数のコンストラクタを定義する場合に
 補助コンストラクタと呼ばれるコンストラクタを使う
 => this() で実装

サンプル

class HelloWorld(val greeting: String, val name: String) {
  println(s"${greeting}, ${name}!!!")

  // ★ここ★
  def this(name: String) = this("Hi", name)
  def this() = this("World")
}

object Hello {
  def main(args: Array[String]): Unit = {
    val helloWorld1 = new HelloWorld("Good morning", "Mike") // Good morning, Mike!!!
    val helloWorld2 = new HelloWorld("Tom") // Hi, Tom!!!
    val helloWorld3 = new HelloWorld() // Hi, World!!!
    println("Done!")
  }
}

【3】継承

1)構文

class <クラス名> <クラス引数> (extends <スーパークラス>)? (with <トレイト名>)* {
  (<フィールド定義> | <メソッド定義>)*
}

2)継承させない - final

final class ClassName

【4】その他クラス

1)抽象クラス

abstract class <クラス名> '(' (<引数名1> : <引数型1>, <引数名2>: <引数型2> ...)? ')' {
  (<フィールド定義> | <メソッド定義> )*
}

// クラスの前にabstract 修飾子をつける
abstract class DemoAbstractClass {

2)ケースクラス

case class <クラス名> '(' (<引数名1> : <引数型1>, <引数名2>: <引数型2> ...)? ')' {
  (<フィールド定義> | <メソッド定義> )*
}

// クラスの前にcase をつける
case class Sample(num: Int)

普通のクラスとの違い

[1] new を使わなくても生成可能
[2] 指定しなくても基本コンストラクタのフィールドにvalが付与
[3] 自動的に equals/canEqual/hashCode/toString/copy() を実装
[4] コンパニオンオブジェクトを自動生成し、apply/unapply()を自動実装

https://qiita.com/chimeiwang/items/b776c032bc4d4b687c32

3)オブジェクト - object

* シングルトンオブジェクトを作る

https://scala-text.github.io/scala_text/object.html

object <オブジェクト名> extends <クラス名> (with <トレイト名>)* {
  (<フィールド定義> | <メソッド定義>)*
}

4)コンパニオンオブジェクト

* クラス名と同じ名前をつけたシングルトンのオブジェクト

効果

* 同名のクラスのprivateメンバにアクセス可能
* 共通の処理、操作を扱える

関連記事

Scala ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/03/10/193805
Scala ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/12/184331
Scala ~ 基本編 / メソッド ~
https://dk521123.hatenablog.com/entry/2023/03/03/000000
Scala ~ 基本編 / トレイト ~
https://dk521123.hatenablog.com/entry/2023/09/10/204016
Scala ~ 基本編 / コレクション ~
https://dk521123.hatenablog.com/entry/2023/03/13/000345
ScalaYAML
https://dk521123.hatenablog.com/entry/2023/03/16/012034