인터페이스와 필드를 클래스 사이에서 공유할 때 사용
자바8의 인터페이스와 유사한다. 클래스와 오브젝트는 트레이트를 확장하고 상속받을수 있으나, 트레이트는 인스턴스화 될 수 없으므로 파라미터가 없다.
키워드 tratit 사용하고 지시자 사용
trait HairColor
generic 타입와 추상화 메소드를 같이 사용하면 유용하게 쓰일수 있다.
trait Iterator[A] {
def hasNext: Boolean
def next(): A
}
trait Iterator[A]:
def hasNext: Boolean
def next(): A
→ generic type이 [A] 이다.
→ 트레이트를 확장하려면 A타입을 구체화해야하고 메소드를 선언해야 한다.
extends 키워드로 트레이드를 확장해서 쓸수있으며 abstract멤버를 사용할 때는 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) {
val t = current
current += 1
t
} else 0
}
}
val iterator = new IntIterator(10)
iterator.next() // returns 0
iterator.next() // returns 1
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 = new IntIterator(10)
iterator.next() // returns 0
iterator.next() // returns 1
트레이트 이터레이터를 확장해서 클래스에서 사용하고 있는 예시가 포인트이다.
트레이트가 필요한 상황이라면, 트레이트의 하위 타입도 대신 쓸수 있다.
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 = new Dog("Harry")
val cat = new Cat("Sally")
val animals = ArrayBuffer.empty[Pet]
animals.append(dog)
animals.append(cat)
animals.foreach(pet => println(pet.name)) // Prints Harry Sally
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]
animals.append(dog)
animals.append(cat)
animals.foreach(pet => println(pet.name)) // Prints Harry Sally
val animals = ArrayBuffer.empty[Pet]
→ 이게 핵심이다.