Scala 抽象类型、复合类型、自类型

抽象类型


特质与抽象类可以具有抽象类型成员,这意味着具体实现将会定义这些成员的实际类型。通常,使用抽象类型的特质或类常常与匿名类实例化一起使用。

# 定义特质(使用抽象类型)
trait Buffer {
  type T
  val element: T
}

# 定义抽象类(使用抽象类型)
abstract class SeqBuffer extends Buffer {
  type U
  type T <: Seq[U]
  def length = element.length
}

# 指定类型参数U
abstract class IntSeqBuffer extends SeqBuffer {
  type U = Int
}

# 匿名类实例化指定抽象类型
def newIntSeqBuf(elem1: Int, elem2: Int): IntSeqBuffer =
  new IntSeqBuffer {
       type T = List[U]
       val element = List(elem1, elem2)
     }

可以将抽象类型转为类型参数,反之亦然。

abstract class Buffer[+T] {
  val element: T
}
abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T] {
  def length = element.length
}

def newIntSeqBuf(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] =
  new SeqBuffer[Int, List[Int]] {
    val element = List(e1, e2)
  }

note:需要使用变化注解隐藏方法newIntSeqBuf返回的对象的实际序列实现类型。
note:存在一些无法将抽象类型替换为类型参数的情况。

复合类型


复合类型用于表达对象的类型同时为多个其他类型的子类型,即复合类型为对象类型的交叉点。

# 定义特质
trait Cloneable extends java.lang.Cloneable {
  override def clone(): Cloneable = {
    super.clone().asInstanceOf[Cloneable]
  }
}
trait Resetable {
  def reset: Unit
}

# 使用复合类型
# 对象obj同时为Cloneable与Resetable的子类型
def cloneAndRest(obj: Cloneable with Resetable): Cloneable={
    val cloned = obj.clone()
    obj.reset
    cloned
}

复合类型可以由多个对象类型构成,这些对象类型可以有单个细化,用于缩短已存在对象成员的签名。通用格式:A with B with C …

自类型


自类型用于表示一个特质必须混入其他特质,即使它没有被直接扩展。这使得依赖成员可以在没有导入的情况下被使用。

自类型用于缩短this类型或其他别名为this的标识符。它的语法与函数语法类似,但是意义完全不同。

trait User {
  def username: String
}

# 使用自类型
trait Tweeter {
  this: User =>
  def tweet(tweetText: String) = println(s"$username: $tweetText")
}

# 混入特质
class VerifiedTweeter(val username_ : String) extends Tweeter with User { 
	def username = s"real $username_"
}

note:扩展了Tweeter的VerifiedTweeter,必须混入User。

翻译源:Scala Tour

猜你喜欢

转载自blog.csdn.net/qq_32165041/article/details/83578470