1)可以把trait作为接口来使用,scala没有implement关键字
继承trait和class 都是使用 extends
scala 继承多个trait 可以使用with关键字
trait A {def AFuc(a:String)}
trait B {def BFuc(b:String)}
class Person(val name:String) extends A with B {
println("Person:"+name)
def AFuc(a:String) = println("a is " + a)
def BFuc(b:String) = println("b is " + b)
}
object Person{
def main(args: Array[String]): Unit = {
var p =new Person("PPP")
p.AFuc("AAA")
p.BFuc("BBB")
/* Person:PPP
a is AAA
b is BBB*/
}
}
2)Trait 可以定义具体函数,具体的field
trait Logger {
def log(msg:String) = println(msg)
}
class Person extends Logger
trait具体 field
trait Human {
val eyeNum:Int = 2
}
class Student extends Human
trait A {
val a:Int
}
class B extends A {
val a = 5
}
3)为实例混入trait
/**
* 为实例混入trait
*/
/
trait Logged{
def log(msg:String){}
}
trait Mylogger extends Logged{
override def log(msg:String): Unit ={
print("log:"+msg)
}
}
class traitDemo(val name:String)extends Logged {
def sayHello: Unit ={
print("Hi,I`m"+name);
log("syaHello is invoked")
}
}
object traitDemo{
def main(args: Array[String]): Unit = {
val p1=new traitDemo("wang")
p1.sayHello//Hi,I`mwang
val p2=new traitDemo("suojie") with Mylogger
p2.sayHello//Hi,I`msuojielog:syaHello is invoked
}
}
4)在trait中定义具体字段
/**
* 在trait中定义具体字段
*/
trait Person{
val eyeNum:Int=2
}
class traitDemo(val name:String)extends Person {
def sayHello: Unit ={
print("Hi,I`m"+name+",I have"+eyeNum+"eyes")
}
}
object traitDemo{
def main(args: Array[String]): Unit = {
val p1=new traitDemo("wang")
p1.sayHello//Hi,I`mwang,I have2eyes
}
}
5)trait调用链
/*
scala中支持让类继承多个trait后,依次调用多个trait中的同一个方法,只要让多个trait的同一个方法中,在
最后都执行super方法即可
类中调用多个trait都有的这个方法时:
首先会从最右边的trait方法开始执行,然后依次往左执行,形成一个调用链条
这种特性非常强大,其实就是相当于设计模式中的责任链模式的一个具体实现
*/
trait Hander{
def handle(data:String): Unit ={
}
}
trait DataVaildHandler extends Hander{
override def handle(data: String){
println("check data "+data)
super.handle(data)
}
}
trait SingnatureVaildHandler extends Hander{
override def handle(data: String) {
println ("check singnature "+data)
super.handle(data)
}
}
class Person(var name:String) extends SingnatureVaildHandler with DataVaildHandler {
def sayHello: Unit ={
println("Hi,I`m "+name);
handle(name)
}
}
object Person{
def main(args: Array[String]): Unit = {
val p=new Person("wang")
p.sayHello
/* Hi,I`m wang
check data wang
check singnature wang*/
}
}
6)scala中混合使用trait的具体方法和抽象方法
trait Valid{
def getName:String//抽象方法
def valid:Boolean ={
getName=="wang"
}
}
class Person(val name:String) extends Valid {
def getName=name
println(valid)
}
object Person{
def main(args: Array[String]): Unit = {
val p=new Person("wang")
p.valid// println(valid)
}
}
7)scala的构造函数
/*
在scala中,trait也有构造代码,就是trait中不包含在任何方法中的代码
继承trait类的构造机制如下:
1.父类的构造函数执行
2.trait的构造代码执行,多个trait从左到右依次执行
3.构造trait时会先构造父trait,如果多个trait继承同一个父trait,
则父trait只构造一次
4.所有trait构造完毕之后,子类的构造函数执行*/
class Person{
println("Person's 的构造函数")
}
trait Logger{
println("Logger's 的构造函数")
}
trait MyLogger extends Logger{
println("MyLogger的构造函数")
}`
trait TimeLogger extends Logger{
println("TimeLoggerD的构造函数")
}
class Student extends Person with MyLogger with TimeLogger{
println("Student的构造函数")
}
object Student{
def main(args: Array[String]): Unit = {
val s=new Student
/*Person's 的构造函数
Logger's 的构造函数
MyLogger的构造函数
TimeLoggerD的构造函数
Student的构造函数
*/
}
}
8)trait变量初始化
方式01:
/*
在scala中,trait没有接收参数的构造函数,只能使用scala中特殊的一种高级特性--提前定义*/
trait SayHello{
val msg:String
println(msg.toString)
}
class Person extends {
val msg:String="init"
}with SayHello{}
object Person{
def main(args: Array[String]): Unit = {
val p=new Person
p.msg
}
}
方式02:
//使用lazy value
trait SayHello{
lazy val msg:String =null
println(msg.toString)
}
class Person extends SayHello{
override lazy val msg: String = "init"
}
object Person{
def main(args: Array[String]): Unit = {
val p=new Person()
p.msg//init
}
}
9)trait继承class
/*
trait继承class,这个class就是所有继承trait类的父类
*/
class MyUtil{
def printMessage(msg:String)=println("被继承的类: "+msg)
}
trait Logger extends MyUtil{
def log(msg:String)={
printMessage("log: "+msg)
}
}
class Person(val name:String)extends Logger{
def sayHello{
log("HI,我是 "+name)
printMessage("你好,我是 "+name)
}
}
object Person{
def main(args: Array[String]): Unit = {
val p=new Person("wang")
p.sayHello
/* 被继承的类: log: HI,我是 wang
被继承的类: 你好,我是 wang*/
}
}