Descripción
- En el lenguaje Scala, los rasgos se utilizan para reemplazar el concepto de interfaces. En otras palabras, cuando varias clases tienen las mismas características, las características se pueden separar y declarar usando la palabra clave trait.
- En las características de Scala, puede haber atributos abstractos y métodos abstractos, así como atributos no abstractos y métodos no abstractos.
- Una clase se puede mezclar con múltiples rasgos.
Combina rasgos únicos
object Scala03_Trait {
def main(args: Array[String]): Unit = {
val stu:PersonTrait03 = new Student03
stu.sleep()
stu.eat()
println(stu.name)
}
}
trait PersonTrait03 {
// 特质中既可以有抽象属性和抽象方法
var name: String
def sleep(): Unit
// 也可以有非抽象属性和非抽象方法
var age: Int = 18
def eat(): Unit = {
println("Person eat")
}
}
// 混入特质
class Student03 extends PersonTrait03 {
// 重写特质中的抽象方法和属性
override var name: String = "Li Ming"
override def sleep(): Unit = {
println("Student sleep")
}
}
Mezclar múltiples rasgos
- Mezcla de múltiples rasgos sin herencia de clases: extiende el rasgo1 con el rasgo2 con…
- Hay varios rasgos que tienen herencia de clases mezclada, primero heredan la clase y luego mezclan el rasgo: extiende ClassName con trait1 con trait2…
- Al crear un objeto, mezcle dinámicamente rasgos: new ClassName con trait1 {sobrescribir método abstracto}.
object Scala04_Trait {
def main(args: Array[String]): Unit = {
/*val clzz = new MyClass04
clzz.mA()
val clazz1 = new MyClass004
clazz1.mB()*/
// 动态的混入特质
val clzz004 = new MyClass004 with TraitC {
override def mC(): Unit = {
println("mC")
}
}
clzz004.mC()
}
}
trait TraitA {
def mA(): Unit
}
trait TraitB {
def mB(): Unit
}
trait TraitC {
def mC(): Unit
}
class Super {
}
// 没有类继承的混入多个特质
class MyClass04 extends TraitA with TraitB with TraitC {
override def mA(): Unit = {
println("mA")
}
override def mB(): Unit = {
println("mB")
}
override def mC(): Unit = {
println("mC")
}
}
// 有继承,混入多个特质。继承的类放在第一个位置
class MyClass004 extends Super with TraitA with TraitB{
override def mA(): Unit = {
println("mA")
}
override def mB(): Unit = {
println("mB")
}
}
Conflicto de rasgos (conflicto ordinario)
- Cuando una clase se mezcla con múltiples rasgos, si no hay relación entre los dos rasgos, pero hay un método abstracto con el mismo nombre, el método abstracto debe reescribirse.
- Cuando una clase se mezcla con múltiples rasgos, si no hay relación entre los dos rasgos, pero hay un método no abstracto con el mismo nombre, el método no abstracto debe reescribirse.
object Scala05_Trait {
def main(args: Array[String]): Unit = {
val p = new Person05
p.m1()
val p2 = new Person005
p2.m1()
}
}
trait Person05TraitA {
def m1(): Unit
}
trait Person05TraitB {
def m1(): Unit
}
class Person05 extends Person05TraitA with Person05TraitB {
override def m1(): Unit = {
println("Person05中重写的m1方法")
}
}
trait Person005TraitA {
def m1(): Unit = {
println("Person005TraitA m1")
}
}
trait Person005TraitB {
def m1(): Unit = {
println("Person005TraitA m1")
}
}
class Person005 extends Person005TraitA with Person005TraitB {
override def m1(): Unit = {
println("Person005中重写的m1方法")
}
}
Apilamiento de rasgos (problema de diamantes)
Descripción
El rasgo A y el rasgo B se mezclan con el rasgo C. El rasgo A y el rasgo B reescriben el método m1 en el rasgo C. Una clase combina la característica A y la característica B al mismo tiempo, entonces, ¿qué método se ejecuta el método m1 en esta clase? Este es el problema de los diamantes.
Código
object Scala06_Trait {
def main(args: Array[String]): Unit = {
val operation = new MyOperation
println(operation.m1()) // 我的操作是:向HDFS向数据库插入数据
}
}
trait Operation {
def m1(): String = {
"插入数据"
}
}
trait DBOperation extends Operation {
override def m1(): String = {
"向数据库" + super.m1() }
}
trait HDFSOperation extends Operation {
override def m1(): String = {
"向HDFS" + super.m1()
}
}
class MyOperation extends DBOperation with HDFSOperation with Operation {
override def m1(): String = {
"我的操作是:" + super.m1()
}
}
Análisis de resultados de ejecución
- El primer paso: enumere la relación de herencia del primer rasgo mezclado como un orden temporal.
DBOperation -> Operación - Paso 2: enumere la relación de herencia del segundo rasgo y superponga el orden antes del orden del primer rasgo. Cabe señalar que los rasgos que ya han aparecido no se repetirán.
HDFSOperation -> DBOperation -> Operation - Paso 3: coloque la subcategoría primero en la secuencia de apilamiento temporal, que es la secuencia de apilamiento final.
MyOperation -> HDFSOperation -> DBOperation -> Operation
Nota: El super en el caso no significa su objeto de rasgo padre, sino el siguiente rasgo en la secuencia de apilamiento anterior.