classとメソッドとフィールドとアクセス修飾子


class

クラス定義はだいたいJavaと同じです。

class Point1(_x: Int, _y: Int) {
  val x = _x
  val y = _y
  // クラスの定義とコンストラクタは同時に書けます。
}

コンストラクタ引数をそのままフィールドにする場合は次のようにできます。

class Point1(val x: Int, val y: int)

Scalaでは複数のコンストラクタを定義できます。しかし、基本的に1つのコンストラクタしか使いません。

コンストラクタ引数のスコープはクラス全体に及びます。

最初のコンストラクタをプライマリーコンストラクタと呼びます。

プライマリーコンストラクタの引数に"var"もしくは"val"をつけると、そのフィールドは公開され外部からアクセスできるようになります。

メソッドのアクセス修飾子

メソッドを定義するときにアクセス修飾子を指定できます。

修飾子 意味
private そのクラス内だけからアクセス可能
protected 派生クラスからのみアクセス可能
private[this] 同じオブジェクトからのみアクセス可能
private[package名] 同一パッケージに所属しているものからのみアクセス可能
protected[package名] 派生クラスに加えて同じパッケージに所属しているもののみアクセス可能
何もなし どこからでもアクセス可能

複数の引数リスト

メソッドは複数の引数リストを取ることができます。

複数の引数ではありません

class Adder {
  def add(x: Int)(y: Int): Int x + y
}
val adder = new Adder()
println(adder.add(3)(4) )
// 引数の括弧1つが1つの引数リストです

複数の引数リストを持ったメソッドは部分適用ができます。

class Mul {
  def mul(x: Int)(y: Int): Int x * y
}
val multi1 = new Mul()
val multi2 = multi1.mul(2)_
println(multi2(3) )
// 部分適用を使う場合には、あとから渡したい引数の部分を_(アンダースコア)で記述する

フィールド

フィールドの定義は次のようになります。

(修飾子) (var/val) fieldName: type = Expression

アクセス修飾子は次のようになります。

修飾子 意味
private そのクラス内だけからアクセス可能
protected 派生クラスからのみアクセス可能
private[this] 同じオブジェクトからのみアクセス可能
private[package名] 同一パッケージに所属しているものからのみアクセス可能
protected[package名] 派生クラスに加えて同じパッケージに所属しているもののみアクセス可能
何もなし どこからでもアクセス可能

メソッドのアクセス修飾子と同じです。 しかし、private[this]はJVMレベルでのフィールドへの直接アクセスのため若干高速です。 細かいレベルでのパフォーマンス・チューニングをするなら意識すると良いでしょう

継承

継承には2つの目的があります。

  • 継承にはスーパークラスの実装をサブクラスでも使うことで実装再利用することです。
  • 複数のサブクラスが共通のスーパークラスのインターフェースを継承することで処理を共通化することです。

Javaでは実装継承が1つだけに限定されています。しかし、Scalaではトレイトという仕組みによって複数の実装継承を実現しています。

class Aprinter() {
  def print(): Unit = {
    println("A")
  }
}
class Bprinter() {
  override def print(): Unit = {
    println("B")
  }
}
new Aprinter().print()
new Bprinter().print()
// 基本的に継承の動きはJavaと同じです
// 既存のメソッドをオーバーライドするときは"override"キーワードを使わなければなりません