特征(Trait)
* 说明
* 1. scala中的Trait,相当于java中的接口+抽象类,可以实现多继承
* 2. trait中可以有抽象属性和抽象方法 也可以有非抽象属性和方法
* 3. 一个类可以继承多个trait / 一个类可以混入(mixin)多个特质
* 语法
* 声明
* trait 名称 { 成员 }
* 继承
* 没有父类 class 类名 extends 特征1 with 特征2 ...
* 有父类 class 类名 extends 父类 with 特征1 with 特征2 ...
* 说明
* 1. 当一个继承trait时,第一个trait用extends,第二个用with
* 2. 同时继承trait和父类时,父类写在extends后面,trait写在with后面
*
动态混入
* 创建对象时mixin 特质,无需在类定义时mixin
* 示例
* var obj = new 对象名称 with 特质1 { 实现 }
*
* 混入多个特质,且多个特质具有相同属性/方法
* 示例
* with Atrait with Btrait
* 情况1
* Atrait、Btrait无关
* 1. 当属性或方法相同时,必须在实现类中重写相同的方法或属性
* 2. 当非抽象属性相同时,他们必须为val变量
* 情况2(特质叠加)
* Atrait、Btrait有关有共同的父类 Ctrait (钻石问题)
* 示例
* class ThreeClass extends Atrait with Btrait
* 说明
* 1. 当属性或方法相同时,优先按继承顺序,使用靠后的特质
* ThreeClass -> Btrait -> Atrait -> Ctrait
* ThreeClass.super = Btrait
* Btrait.super = Atrait
* Atrait.super = Ctrait
* 2. 在实现类中可以使用 super[特质名称].成员 来限制继承顺序
*
特质自身类型
* 说明
* 自身类型可以实现依赖注入功能
* 语法
* _: traitName =>
* 等价于 混入traitName
*
* */
package com.dawang.scala.面向对象
/**
* @author gaocun
* @create 2021-10-25 6:41 PM */
class Trait_12 {
/*
* 特征(Trait)
* 说明
* 1. scala中的Trait,相当于java中的接口+抽象类,可以实现多继承
* 2. trait中可以有抽象属性和抽象方法 也可以有非抽象属性和方法
* 3. 一个类可以继承多个trait / 一个类可以混入(mixin)多个特质
* 语法
* 声明
* trait 名称 { 成员 }
* 继承
* 没有父类 class 类名 extends 特征1 with 特征2 ...
* 有父类 class 类名 extends 父类 with 特征1 with 特征2 ...
* 说明
* 1. 当一个继承trait时,第一个trait用extends,第二个用with
* 2. 同时继承trait和父类时,父类写在extends后面,trait写在with后面
*
* 动态混入
* 创建对象时mixin 特质,无需在类定义时mixin
* 示例
* var obj = new 对象名称 with 特质1 { 实现 }
*
* 混入多个特质,且多个特质具有相同属性/方法
* 示例
* with Atrait with Btrait
* 情况1
* Atrait、Btrait无关
* 1. 当属性或方法相同时,必须在实现类中重写相同的方法或属性
* 2. 当非抽象属性相同时,他们必须为val变量
* 情况2(特质叠加)
* Atrait、Btrait有关有共同的父类 Ctrait (钻石问题)
* 示例
* class ThreeClass extends Atrait with Btrait
* 说明
* 1. 当属性或方法相同时,优先按继承顺序,使用靠后的特质
* ThreeClass -> Btrait -> Atrait -> Ctrait
* ThreeClass.super = Btrait
* Btrait.super = Atrait
* Atrait.super = Ctrait
* 2. 在实现类中可以使用 super[特质名称].成员 来限制继承顺序
*
* 特质自身类型
* 说明
* 自身类型可以实现依赖注入功能
* 语法
* _: traitName =>
* 等价于 混入traitName
*
* */
}
package Outer12 {
// 声明 trait
trait OneTrait {
// 抽象属性 + 非抽象属性
var id: Int
var name: String = "大王"
// 抽象方法 + 非抽象方法
def abs_show
def show = println("OneTrait - 非抽象方法")
println("OneTrait - 主构造器")
}
class OneClass {}
trait Atrait {
val id: Int = 1
val name = "Atrait"
def show = println("Atrait - show")
}
trait Btrait {
val id: Int = 2
val name = "Btrait"
def show = println("Btrait - show")
}
// 声明类 混入多个特质(A B且A、B无关)
class TwoClass extends Atrait with Btrait {
override def show: Unit = println("TwoClass - 重新show方法")
override val id: Int = 88
override val name = "OneClass"
}
trait Ctrait {
val id = 1
val name = "Ctrait"
def show = {
println("Ctrait - show执行了")
"Ctrait"
}
}
trait Dtrait extends Ctrait {
override val id = 2
override val name = "Dtrait"
override def show = {
println("Dtrait - show执行了")
super.show + "-" + "Dtrait"
}
}
trait Etrait extends Ctrait {
override val id = 3
override val name = "Etrait"
override def show = {
println("Etrait - show执行了")
super.show + "-" + "Dtrait"
}
}
class ThreeClass extends Etrait with Dtrait with Ctrait {
// 使用super[]来指定混入的trait
override def show: String = super[Ctrait].show
}
// 测试
object test12 {
def main(args: Array[String]): Unit = {
// 动态混入
var obj = new OneClass with OneTrait {
override var id: Int = 99
override def abs_show: Unit = "OneTrait - 动态混入"
}
println(obj.id)
println(obj.name)
obj.show
obj.abs_show
println("===========================")
var obj1 = new TwoClass()
obj1.show
println(obj1.id)
println(obj1.name)
println("===========================")
var obj2 = new ThreeClass()
println(obj2.id)
println(obj2.name)
println(obj2.show)
println("===========================")
}
}
}
package Outer12_1 {
// 定义类
class User(val id: Int, val name: String)
// 定义Dao特质
trait Dao {
// 非抽象方法
def insert(user: User) = {
println("insert into database" + user.name)
}
println("Dao - 主构造器")
}
// 定义APP特质
trait App {
// 依赖注入
_: Dao =>
// 非抽象方法
def login(user: User) = {
println("login :" + user.name)
insert(user)
}
}
// 实现类
object MyApp extends App with Dao {
def main(args: Array[String]): Unit = {
login(new User(10,"大王"))
}
}
}