【Scala十二】Scala核心六:Trait

Traits are a fundamental unit of code reuse in Scala. A trait encapsulates method and field definitions, which can then be reused by mixing them into classes. Unlike class inheritance, in which each class must inherit from just one superclass, a class can mix in any number of traits. Once a trait is defined, it can be mixed in to a class using either the extends or with keywords.

 

trait类似Java中可以带有实现的接口,Java中有多接口继承,scala中有多trait集成

 

trait相对于普通的类,不管是具体类,还是抽象类,一个重要的差别是trait的主构造函数不能带有参数,

例如

trait ThisIsTrait(arg: String)

 

定义了多个trait的Animal类:

 

package spark.examples.scala.twaits

trait Animal {
  def weight = 0

  //抽象方法
  def speak
}

trait HasLegs {
  def numLegs = 0
}

trait CanClimbTree {
  def canClimeTree = false
}

trait GenericsTrait[T] {
  def get: T
}

trait Getter1 {
  def duplicateGet = 101

  def duplicateGet2 = 1012
}

trait Getter2 {
  def duplicateGet = 102
  def duplicateGet2 = 2012
}

trait Getter3 {
  def getIt = 100
}

//trait跟class的一个重要区别是,trait主构造函数不能有参数,如下错误
/*
trait
 */

 

 mixin trait的具体类:Cat

 

package spark.examples.scala.twaits

//The first one uses Animal; the others use with,one with for each
class Cat(name: String) extends Animal with HasLegs with CanClimbTree with GenericsTrait[Int] with Getter1 with Getter2 with Getter3 {

  override def weight: Int = 3

  override def numLegs: Int = 4

  override def canClimeTree: Boolean = true

  //抽象方法
  override def speak: Unit = {
    println("Miao")
  }

  override def toString: String = {
    "I am a cat: " + name
  }

  override def duplicateGet = 300

  override def get = {
    super.duplicateGet + 100 //为什么super指向的是Getter2而不是Getter1
  }

  override def duplicateGet2 = {
    super.duplicateGet2 + 10001 //为什么super指向的是Getter2而不是Getter1
  }

  override def getIt: Int = {
    super.getIt + 120
  }

}

 

调用程序

 

package spark.examples.scala.twaits


object TwaitTest {
  def main(args: Array[String]) {
    val c = new Cat("kitty")
    c.speak
    println(c.numLegs)
    println(c.canClimeTree)
    println(c.get)
    //两个trait定义了相同的方法并且提供了实现,那么Scala会报方法冲突,解决办法,实体类进行重写
    println(c.duplicateGet)
    //通过super调用父实现
    println(c.getIt)
    println(c.duplicateGet2)
  }
}

 

 问题:在使用super.methodName时,如果多个trait都有那个方法时,为什么一直都是最后一个起作用,如果要让第一个起作用,该如何操作?

 

你可能感兴趣的:(scala)