天天看点

scala特质特质

特质

1.trait 关键字定义特质

** 特质类似java中的接口,功能却比接口更加丰富,其实他更似一个类,唯一区别就是没有带参构造**
** trait 关键字定义特质 **
**  类,特质可以用 extends混入第一个特质,也可以再之后用with 混入更多特质 **
           
/**
  * 分别定义两个特质
  */
trait Attribute {
  //可以存在一个抽象属性
  val subject: String

  //也可以定义具体实现
  val state = "活着的"
  val name = "我是谁"
}

trait Motion {
  //抽象方法
  def move()

  //具体实现的方法。(带有{},即表明该方法是一个已经实现了方法,不是抽象方法)
  def eat(s: String) {}
}
           

2.类中混入特质

/**
  * 一个具体的类可以使用关键字extends混入第一个特质,也可以再之后用with 混入更多特质,
  * 非抽象类混入特质,必须实现其抽象的方法或者属性,此时可以不用关键字 override 修饰
  * 如果要覆盖掉特质中已经实现的方法或者属性 则必须加 override 修饰
  * @param myname
  */
class Human(val myname: String) extends Attribute with Motion {

  //必须实现抽象属性,可以不用override关键字
  val subject = "人类"
  def move(): Unit = ???

  //覆盖已经实现的属性或者方法 必须使用override关键字
  override val name = myname
  override def eat(s: String): Unit = {println(name+"吃了"+s)}

  //类中定义的方法,打印对象信息
  def printAttribute(): Unit = {
    println(state + subject + name)
  }
}

           
/**
  * 调用
  */
object Client extends App {

  private val human = new Human("张三")

  human.printAttribute()
  human.eat("面包")
}
           
  • 执行结果
活着的人类张三
张三吃了面包

Process finished with exit code 0
           

3.对象中混入特质(with)

/**
  * 定义个类
  */
class Animal {}

object AnimalClient extends App {

  //对象混入特质
  private val dog = new Animal with Attribute with Motion {
    
    //必须实现抽象方法和属性
    val subject = "动物"
    def move(): Unit = println(name + "跑了起来")
    
    //可以覆写已经实现的方法和属性
    override val name = "狗"
    override def eat(s: String): Unit = println(name + "吃" + s)

  }

  println(dog.subject)
  println(dog.name)
  dog.eat("骨头")
  dog.move()
  
}
           

执行结果

动物
狗
狗吃骨头
狗跑了起来

Process finished with exit code 0
           

4.特质中调用super

/**
  * 特质中的super 调用的是下一层级中的方法 他仍然是一个抽象的
  * 必须添加 abstract override
  */
trait Botany extends Motion {
  abstract override def move(): Unit = super.move()
}