特质
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()
}