Scala之旅-特征

Scala之旅-特征

特征(Traits)

特征的作用是在类之间分享接口和数据域,与Java 8中的接口类似。类和对象可以扩展特征,但是特征无法被实例化,因此特征是没有参数的。

定义特征

一个最简单的特征只包含关键字trait和标识符:

trait HairColor

当特征作为带有抽象方法的泛型类型时就变得格外有用:

trait Iterator[A] {
  def hasNext: Boolean
  def next(): A
}

扩展特征Iterator[A]时需要一个类型A以及对方法hasNext和next的实现。

使用特征

使用关键字extends来扩展一个特征。然后用关键字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()  // prints 0
iterator.next()  // prints 1

这个IntIterator类需要一个参数作为上界。它扩展自Iterator[Int],意味着方法next必须返回一个Int值。

子类型化

特征的子类型可以被用在需要该特征的地方。

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

特征Pet有一个抽象域name,name通过Cat和Dog在它们的构造函数中得以实现。在最后一行代码中,我们调用pet.namepet.name必须在特征Pet的所有子类型中得到实现。

参考资料

本文译自Tour Of Scala – Traits

上一篇:Scala之旅-类

下一篇:Scala之旅-使用mixins合成类

发表评论

电子邮件地址不会被公开。 必填项已用*标注