前章:名前付き引数
- トレイトはクラス間でインタフェースやフィールドを共有するために使用される
- Scala2ではトレイトはパラメータを持てなかったが、Scala3からはパラメータを持つことができるようになった
- 参考:https://docs.scala-lang.org/scala3/reference/other-new-features/trait-parameters.html
トレイトを定義し、利用する
traitキーワードでトレイトを定義し、extendsキーワードでクラスにトレイトを継承させる- トレイトは汎用型(
generic type)や抽象メソッドと組み合わせることで特に有用になる
抽象メソッドは
override記述無しでもクラス側で定義可能だが、慣習(継承されたメソッドとして把握する為...)としてoverrideを記述する
trait Iterator[A]:
def hasNext: Boolean
def next(): A
class IntIterator(to: Int) extends Iterator[Int]:
private var current = 0
override def hasNext: Boolean = current < to
override def next(): Int =
if hasNext then
val t = current
current += 1
t
else
0
end IntIterator
val iterator = IntIterator(10)
iterator.next() // returns 0
iterator.next() // returns 1 Subtyping
- トレイトを使用することでクラスをサブタイプとして扱い、ポリモーフィズムを実現することができる
import scala.collection.mutable.ArrayBuffer
trait Pet:
val name: String
class Cat(val name: String) extends Pet
class Dog(val name: String) extends Pet
val dog = Dog("Harry")
val cat = Cat("Sally")
val animals = ArrayBuffer.empty[Pet] // 指定した型の空のArrayBufferを作成する
animals.append(dog)
animals.append(cat)
animals.foreach(pet => println(pet.name))
// Harry
// Sally次章:タプル