7.2 选择性混入
在上面的例子里,Friend
trait混入到了Dog
类里。这样就可以将Dog
的任意实例当作Friend
;也就是说,所有的Dog
都是Friend
。
此外,还可以在实例一级对trait进行选择性混入,这样的话,就可以把特定的类的实例当做trait。我们看个例子:
TraitsAndTypeConversions/Cat.scala
class Cat(val name: String) extends Animal
Cat
并没有混入Friend
trait,所以,不能把Cat
的实例当作Friend
。下面会看到,尝试这么做就会导致编译错误:
TraitsAndTypeConversions/UseCat.scala
def useFriend(friend: Friend) = friend listen
val alf = new Cat("Alf")
val friend : Friend = alf // ERROR
useFriend(alf) // ERROR
错误如下:
(fragment of UseCat.scala):4: error: type mismatch;
found : Cat
required: Friend
val friend : Friend = alf // ERROR
^
(fragment of UseCat.scala):6: error: type mismatch;
found : Cat
required: Friend
useFriend(alf) // ERROR
^
two errors found
!!!
discarding <script preamble>
!!!
discarding <script preamble>
然而,Scala确实可以为爱猫人提供帮助,需要的话,我们可以专门把特殊的宠物当作Friend
。创建实例时,只要简单的用with
关键字标记一下即可:
TraitsAndTypeConversions/TreatCatAsFriend.scala
def useFriend(friend: Friend) = friend listen
val snowy = new Cat("Snowy") with riend
val friend : Friend = snowy
friend.listen
useFriend(snowy)
输出如下:
Your friend Snowy is listening
Your friend Snowy is listening
Scala给予了我们极大的灵活性:把类的所有实例当作trait,或是只选择需要的实例当作trait。如果想把trait用于事先存在的类上,后者就显得有用了。