class Stack[A] {privatevar elements: List[A] = Nildefpush(x: A) { elements = x :: elements }defpeek: A = elements.headdefpop(): A = {val currentTop = peek elements = elements.tail currentTop }}
要使用一个泛类型,将一个具体的类型替换掉A即可。
val stack =new Stack[Int]stack.push(1)stack.push(2)println(stack.pop) // prints 2println(stack.pop) // prints 1
上面的例子中,实例对象接收整型值,如果该类型有子类型,子类型也是可以传入的。
class Fruitclass Apple extends Fruitclass Banana extends Fruitval stack =new Stack[Fruit]val apple =new Appleval banana =new Bananastack.push(apple)stack.push(banana)
class AnimalPrinter extends Printer[Animal] {defprint(animal: Animal): Unit = println("The animal's name is: "+ animal.name)}class CatPrinter extends Printer[Cat] {defprint(cat: Cat): Unit = println("The cat's name is: "+ cat.name)}
trait User {defusername: String}trait Tweeter { this: User =>// 重新赋予 this 的类型deftweet(tweetText: String) = println(s"$username: $tweetText")}class VerifiedTweeter(val username_ : String) extends Tweeter with User { // 我们混入特质 User 因为 Tweeter 需要defusername=s"real $username_"}val realBeyoncé =new VerifiedTweeter("Beyoncé")realBeyoncé.tweet("Just spilled my glass of lemonade") // 打印出 "real Beyoncé: Just spilled my glass of lemonade"
因为我们在特质 trait Tweeter 中定义了 this: User =>,现在变量 username 可以在 tweet 方法内使用。 这也意味着,由于 VerifiedTweeter 继承了 Tweeter,它还必须混入 User(使用 with User)。
abstractclass Monoid[A] {defadd(x: A, y: A): Adefunit: A}object ImplicitTest {implicitval stringMonoid: Monoid[String] =new Monoid[String] {defadd(x: String, y: String): String = x concat ydefunit: String ="" }implicitval intMonoid: Monoid[Int] =new Monoid[Int] {defadd(x: Int, y: Int): Int = x + ydefunit: Int =0 }defsum[A](xs: List[A])(implicit m: Monoid[A]): A =if (xs.isEmpty) m.unitelse m.add(xs.head, sum(xs.tail))defmain(args: Array[String]): Unit = { println(sum(List(1, 2, 3))) // uses IntMonoid implicitly println(sum(List("a", "b", "c"))) // uses StringMonoid implicitly }}
在 main 方法中我们调用了 sum 方法两次,并且只传入参数 xs。 Scala 会在上例的上下文范围内寻找隐式值。 第一次调用 sum 方法的时候传入了一个 List[Int] 作为 xs 的值,这意味着此处类型 A 是 Int。 隐式参数列表 m 被省略了,因此 Scala 将查找类型为 Monoid[Int] 的隐式值。
intMonoid 是一个隐式定义,可以在main中直接访问。 并且它的类型也正确,因此它会被自动传递给 sum 方法。
第二次调用 sum 方法的时候传入一个 List[String],这意味着此处类型 A 是 String。 与查找 Int 型的隐式参数时类似,但这次会找到 stringMonoid,并自动将其作为 m 传入。
import scala.language.implicitConversionsimplicitdeflist2ordered[A](x: List[A]) (implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] =new Ordered[List[A]] { //replace with a more useful implementationdefcompare(that: List[A]): Int =1 }