a19_scala trait特质

scala outline

scala outline

trait作用及代码演示

trait作用

  1. Scala语言中,采用特质trait(特征)来代替java中接口的概念
  2. 特质是对scala中只允许单继承机制的一种补充

trait 代码演示

体会用trait实现以下功能

在这里插入图片描述
基本语法

trait 特质名 {
	代码主体
}

没有父类:class  类名 extends  特质1   with    特质2   with   特质3 …
有父类:class  类名  extends  父类   with  特质1   with   特质2  with 特质3
object Test {
  def main(args: Array[String]): Unit = {
    val c = new C()
    val e = new E()
    c.getConnect() // 链接oracle数据库
    e.getConnect() // 链接mysql数据库
  }
}

trait Trait01 {
  //定义一个规范
  def getConnect(): Unit
}

class A {}

class B extends A {}

// 如果一个类在混入特质和继承父类时,应当把父类写在extends后
class C extends A with Trait01 {
  override def getConnect(): Unit = {
    println("链接oracle数据库...")
  }
}

class D {}

class F extends D {}

class E extends D with Trait01 {
  override def getConnect(): Unit = {
    println("链接mysql数据库...")
  }
}

注意事项

  1. 特质可以同时拥有抽象方法和具体方法,即非抽象方法
  2. 一个类可以混入多个特质
  3. 所有的Java接口都可以当做Scala特质使用

trait 动态混入

作用:可灵活的扩展类的功能

object Test {
  def main(args: Array[String]): Unit = {
    val gir: Person = new Person

    // 男人,需要购买保健品重振雄风,女人却不需要,所以单独为男人混入该特质,即动态混入特质
    // 必须要加返回值类型 Person with C,不然boy对象不可以调用buy这个方法
    val boy: Person = new Person with C {
      override def buy(): Unit = {
        println("男人专享:购买六味地黄丸,重振雄风")
      }
    }
  }
}

// 定义跑步行为
trait A {
  def run(): Unit
}

// 定义讲话行为
trait B {
  def speak(): Unit
}

// 定义购买保健品行为
trait C {
  def buy(): Unit
}

// 我们知道,人可以跑步,讲话,所以可以混入特质A、B,但是男人,需要购买保健品重振雄风,女人却不需要,所以不必混入特质C
class Person extends A with B {
  override def run(): Unit = {
    println("慢悠悠的跑步")
  }

  override def speak(): Unit = {
    println("小心翼翼的讲情话")
  }
}

特质冲突

  1. 一个类混入多个特质,多个特质之间有相同的抽象方法,特质之间没有关系,直接对抽象方法实现一次即可
object Test {
  def main(args: Array[String]): Unit = {
    val c: C = new C
        c.f()
  }
}

trait A {
// 抽象方法
  def f(): Unit
}

trait B {
  def f(): Unit
}

class C extends A with B {
  override def f(): Unit = {
    println("特质A、B的f方法,我谁都不用。我只把你们的方法重写,用我自己的")
  }
}
  1. 一个类混入多个特质,多个特质之间有相同的非抽象方法,特质之间没有关系,应该对相同的非抽象方法进行重写
object Test {
  def main(args: Array[String]): Unit = {
    val c: C = new C
        c.f()
  }
}

// 非抽象方法
trait A {
  def f(): Unit={
    println("特质A")
  }
}

trait B {
  def f(): Unit={
    println("特质B")
  }
}

class C extends A with B {
  override def f(): Unit = {
    println("特质A、B的f方法,我谁都不用。我只把你们的方法重写,用我自己的")
  }
}

特质叠加

什么是特质叠加问题

一个类(Sub)混入的两个trait(TraitA,TraitB)中具有相同的非抽象方法,且两个trait混入相同的trait(TraitC)即及所谓的“钻石问题”,解决这类冲突问题,Scala采用了特质叠加的策略

在这里插入图片描述

处理办法: 加super.方法

解决问题代码演示

object Test {
  def main(args: Array[String]): Unit = {
    val sub: Sub = new Sub
    println(sub.f()) // 输出结果 我的操作是--->向mysql中向hdfs中插入数据
  }
}

trait C {
  def f(): String = {
    "插入数据"
  }
}

trait A extends C {
  override def f(): String = {
    "向mysql中" + super.f()
  }
}

trait B extends C {
  override def f(): String = {
    "向hdfs中" + super.f()
  }
}

class Sub extends B with A {
  override def f(): String = {
    "我的操作是--->" + super.f()
  }
}

上述案例中的super.f()调用的是父trait中的方法吗?

当一个类混入多个特质的时候,scala会对所有的特质及其父特质按照一定的顺序进行排序,而此案例中的super.f()调用的实际上是排好序后的下一个特质中的f()方法。排序规则如下:

  1. 第一步:列出混入的第一个特质B的混入关系,作为临时叠加顺序
    在这里插入图片描述
  2. 第二步:列出混入的第二个特质A的混入关系,并将该顺序叠加到临时顺序前边,已经出现的特质不再重复

在这里插入图片描述

  1. 将子类Sub放在临时叠加顺序的第一个,得到最终的叠加顺序
    在这里插入图片描述
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值