Scala склонен поощрять использование замыканий вместо того типа хуков, о котором вы говорите (большинство из которых он не может реализовать удобно из-за статической типизации и компиляции).
Для этого необходимо заранее знать, где может потребоваться гибкость в обычном поведении, но он очень мощный и простой в использовании, когда он доступен. Например, предположим, у вас есть метод, который печатает имена людей:
case class Name(first: String, last: String) {
def title = last + ", " + first(0).toUpper + "."
}
trait Familiar extends Name {
override def title = first + " " + last(0).toUpper + "."
}
def listing(names: Array[Name]) = names.foreach(name => println(name.title))
val jd1 = new Name("John","Doe)
listing(Array(jd1)) // Prints Doe, J.
val jd2 = new Name("John","Doe") with Familiar
listing(Array(jd2)) // Prints John D.
но если вы действительно собираетесь много менять печать имен, вам лучше встроить это в:
case class Name(first: String, last: String) {
def title = last + ", " + first(0).toUpper + "."
}
def listing(names: Array[Name], address: Name => String = _.title) =
names.map(address).foreach(println)
val jd = new Name("John", "Doe")
listing(Array(jd)) // Uses default, so prints Doe, J.
listing(Array(jd), n => n.first + " " + n.last(0).toUpper + ".") // Prints John D.