内容如下:
1.trait多继承构造器的执行顺序
2.解决报错的代码:空指针异常
3.trait 和 class 的区别
(一)trait多继承构造器的执行顺序
如果是多继承,有多个trait,按书写顺序从左到右
package level02
/*
特质
trait:实现多继承
trait多继承构造器的执行顺序
1. 先父 后子
2. 如果是多继承,有多个trait,按书写顺序从左到右
*/
object class15 {
trait A {
println("A特质构造器")
}
trait B {
println("B特质构造器")
}
trait C {
println("C特质构造器")
}
class Child() extends C with B with A{
println("child...")
} // 继承 三个特质A,B,C
def main(args: Array[String]): Unit = {
val child = new Child()
}
}
运行代码如下:
【实现下图图例 代码示范】
package level02
/*
特质
trait:实现多继承
trait多继承构造器的执行顺序
1. 先父 后子
2. 如果是多继承,有多个trait,按书写顺序从左到右
*/
object class15 {
trait AA {
println("AA 特质构造器")
}
trait A extends AA{
println("A 构造器")
}
trait B {
println("B特质构造器")
}
trait CC {
println("CC 特质构造器")
}
trait C extends CC{
println("C 构造器")
}
class Child() extends C with B with A{
println("child...")
} // 继承 三个特质A,B,C
def main(args: Array[String]): Unit = {
val child = new Child()
}
}
运行代码如下:
(二)解决报错的代码:空指针异常
【代码如下】:
package level02
import java.io.FileWriter
/*
*/
object class16 {
trait FileLogger{
println("FileLogger")
val filename:String
// 懒加载机制 lazy
// 这个对象不会立刻创建,而是等到你需要使用的时候才会创建
lazy val writer = new FileWriter(filename)
def writeLog(msg:String):Unit = {
writer.write(msg)
writer.close()
}
}
class MyWriter extends FileLogger {
println("MyWriter")
override val filename: String = "test.log"
} // 继承 三个特质A,B,C
def main(args: Array[String]): Unit = {
val log = new MyWriter()
log.writeLog("测试内容")
}
}
问题分析:通过打印,引导学生找到问题:调用p.log()时,fileName没有值。这就是继承时带的问题:先执行了trait构造器的代码,后执行了具体子类的构造器。而具体的赋值操作是在子类的构造器中才进行,所以,父类的filename没有值,导致空指针异常。
问题解决:
方法1:懒加载
lazy val fileout = new PrintWriter(filename)
方法2:提前定义
val p = new {override val filename="p052.log"} with Person051
(三)trait 和 class 的区别
相同点:类和trait都可以定义成员变量(抽象,具体);继承时都使用extends关键字
不同点:trait的构造器不能带参数;trait支持多继承
package level02
import java.io.FileWriter
/*
trait 和 class 的区别:
1. class 类。 伴生类,抽象类,内部类,不能多继承。
2. trait 特质。 可以多继承,构造器不能带参数。 extends with
共同点:
1. 都可以有:具体属性,抽象属性。具体方法、抽象方法
2. 都使用extends来继承
*/
object class17 {
class A{}
trait B{}
class AB extends A with B{
}
def main(args: Array[String]): Unit = {
}
}