您现在的位置是:首页 >技术教程 >Scala学习(七)---面向对象特质网站首页技术教程
Scala学习(七)---面向对象特质
1.面向对象特质(Trait)
在Scala语言中,采用特质trait(特征)来代替接口的概念,也就是说,多个类具有相同的特质的时候,就可以将这个特质独立出来,采用关键字trait声明。
 Scala中的trait可以拥有抽象属性和方法,也可以拥有具体的属性和方法,一个类可以混入多个特质(trait),这种感觉相对于Java的抽象类
 Scala引入trait特征,第一用来替代Java的接口,第二也就是对单继承机制的一种补充。
2.特质声明
一个类具有某种特质,就意味着这个类满足了这个特质的所有要素,所以在使用的时候,也采用了extends关键字,如果有多个特制或者存在父类,那么需要采用with关键字进行连接。
 基本语法:
 没有父类:class 类名 extends 特质1 with 特质2 with 特质3…
 有父类:class 类名 extends 父类 with 特质1 with 特质2 …
class TestTrait {
}
object TestTrait
{
  def main(args: Array[String]): Unit = {
    
  }
}
//定义一个特质
trait Age09{
  //抽象的属性和方法
  val age:Int
  def sayHi():Unit
  
  //具体的属性和方法
  val age1:Int=10
  def sayHi1():Unit=println("hi age")
}
trait young09{
  
}
class Father01{
  
}
//实现特质
//有父类的情况
class Children01 extends Father01 with Age09 with young09 {
  override val age: Int = 21
  override def sayHi(): Unit = "hello"
}
//没有父类的情况
class Children02 extends Age09 with young09 {
  override val age: Int = 18
  override def sayHi(): Unit = "hello "
}
 
2.1 特质的特点
a.特质可以同时拥有抽象方法和具体方法
 b.动态混入:可灵活的扩展类的功能
 c.动态混入:创建对象的时候混入trait,而无需使类混入该特质
 d.如果混入的trait有未实现的方法,则需要实现
2.2 特质冲突
当一个类继承的父类和特质有同样的具体属性或者方法时候,调用此属性或者方法时,会报错,此时需要重写属性或者方法来解决冲突。如果属性使用var来修饰,则冲突就无法解决,因为在scala中var修饰的属性不可以重写。
object TestTrait02{
  def main(args: Array[String]): Unit = {
    val child0 = new Child03
    println(child0.age)
  }
}
trait TraitDemo1{
  val age:Int=11
}
//父类
class Father03{
  val age:Int=12
}
//子类
class Child03 extends Father03 with TraitDemo1 {
}
 

2.3 特质叠加

 sub类混入的两个特质TraitA和TraitB,而这两个特质又同时继承了TraitC特质,此种情况称为特质的叠加。
class TestTrait03 {
}
object TestTrait03{
  def main(args: Array[String]): Unit = {
    val sub0 = new sub
    println(sub0.info())
  }
}
trait TraitC{
  val age:Int
  def info():String={
    "age"
  }
}
trait TraitB extends TraitC {
  override val age:Int=12
  override def info():String={
    "young"+super.info()
  }
}
trait TraitA extends TraitC {
  override val age:Int=62
  override def info(): String = {
    "old" + super.info()
  }
}
class sub extends TraitB with TraitA {
  override def info():String="person is"+super.info()
}
 

 可以看到,当一个类中混入多个特质的时候,scala会对所有的特质及其父特质进行一定的顺序进行排序,在上述例子中的顺序为TraitA–>TraitB–>TraitC,这相当于类在混入特质的顺序的倒序class sub extends TraitB with TraitA
 如果想要调用某个指定的混入特质的方法,可以使用super[].方法来实现
super[TraitB].info()
 
2.4 特质自身类型
当一个类混入一个特质的时候,必须要混入这个特质依赖的另一个特质
 语法:_:特质=>
trait Age1{
  
}
trait Young1{
  _:Age1=>
}
class Person10 extends Young1 with Age1 {
  
}
 
2.5 特质和抽象类的区别
优先使用特质,一个类扩展多个特质是很方便的,但是只能扩展一个抽象类
如果需要构造函数参数,使用抽象类。因为抽象类可以定义带参数的构造函数,而特质不行
 
扩展
1.obj.isInstanceOf[T] //判断obj是不是T类型
2.obj.asInstanceOf[T] //将obj强转为T类型
3.classOf获取类模板 //相当于Java中的反射
                
            




U8W/U8W-Mini使用与常见问题解决
QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。...
stm32使用HAL库配置串口中断收发数据(保姆级教程)
分享几个国内免费的ChatGPT镜像网址(亲测有效)
Allegro16.6差分等长设置及走线总结