加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala当中的特质trait

发布时间:2020-12-16 18:56:46 所属栏目:安全 来源:网络整理
导读:1、将trait作为接口使用 Scala中的trait是一种特殊的概念; 首先先将trait作为接口使用,此时的trait就与Java中的接口 (interface)非常类似; 在trait中可以定义抽象方法,就像抽象类中的抽象方法一样,只要不给出方法的方法体即可; 类可以使用 extends 关

1、将trait作为接口使用

  • Scala中的trait是一种特殊的概念;
  • 首先先将trait作为接口使用,此时的trait就与Java中的接口 (interface)非常类似;
  • 在trait中可以定义抽象方法,就像抽象类中的抽象方法一样,只要不给出方法的方法体即可;
  • 类可以使用extends关键字继承trait,注意,这里不是 implement,而是extends ,在Scala中没有 implement 的概念,无论继承类还是trait,统一都是 extends
  • 类继承后,必须实现其中的抽象方法,实现时,不需要使用 override 关键字
  • Scala不支持对类进行多继承,但是支持多重继承 trait,使用 with 关键字即可。

    举例说明:

?????????? ?

????????trait HelloTrait {

??????????def sayHello(): Unit

????????}

????????trait MakeFriendsTrait {

??????????def makeFriends(c: Children): Unit

????????}

????????//多重继承 trait

????????class Children(val name: String) extends HelloTrait with MakeFriendsTrait with Cloneable with Serializable{

??????????def sayHello() =println("Hello," + this.name)

??????????def makeFriends(c: Children) = println("Hello,my name is " + this.name + ",your name is " + c.name)

????????}

????????object Children{

??????????def main(args: Array[String]) {

????????????val c1=new Children("tom")

????????????val c2=new Children("jim")

????????????c1.sayHello()//Hello,tom

????????????c1.makeFriends(c2)//Hello,my name is tom,your name is jim

??????????}

????????}

? ?

2、在trait中定义具体的方法

  • Scala中的trait不仅可以定义抽象方法,还可以定义具体的方法,此时 trait 更像是包含了通用方法的工具,可以认为trait还包含了类的功能。

    举例说明:

????/**

???? * 比如 trait 中可以包含很多子类都通用的方法,例如打印日志或其他工具方法等等。

???? * spark就使用trait定义了通用的日志打印方法;

???? */

????trait Logger {

??????def log(message: String): Unit = println(message)

????}

????class PersonForLog(val name: String) extends Logger {

??????def makeFriends(other: PersonForLog) = {

????????println("Hello," + other.name + "! My name is " + this.name + ",I miss you!!")

????????this.log("makeFriends method is invoked with parameter PersonForLog[name = " + other.name + "]")

??????}

????}

????object PersonForLog{

??????def main(args: Array[String]) {

????????val p1=new PersonForLog("jack")

????????val p2=new PersonForLog("rose")

????????p1.makeFriends(p2)

????????//Hello,rose! My name is jack,I miss you!!

????????//makeFriens method is invoked with parameter PersonForLog[name = rose]

??????}

????}

? ?

3、在trait中定义具体field

  • Scala 中的 trait 可以定义具体的 field,此时继承 trait 的子类就自动获得了 trait 中定义的 field;
  • 但是这种获取 field 的方式与继承 class 的是不同的。 如果是继承 class 获取的 field ,实际上还是定义在父类中的;而继承 trait获取的 field,就直接被添加到子类中了。

    举例说明:

???????? ?

????????trait PersonForField {

??????????val??age:Int=50

????????}

???????? ?

????????//继承 trait 获取的field直接被添加到子类中

????????class StudentForField(val name: String) extends PersonForField {

??????????def sayHello = println("Hi,I‘m " + this.name + ",my??age??is "+ age)

????????}

???????? ?

????????object StudentForField{

??????????def main(args: Array[String]) {

????????????val s=new StudentForField("tom")

????????????s.sayHello

??????????}

? ?

}

4、在trait中定义抽象field

  • Scala中的trait也能定义抽象field, 而trait中的具体方法也能基于抽象field编写;
  • 继承trait的类,则必须覆盖抽象field,提供具体的值;

    举例说明:

? ?

????trait SayHelloTrait {

??????val msg:String

??????def sayHello(name: St

????ring) = println(msg + "," + name)

????}

???? ?

????class PersonForAbstractField(val name: String) extends SayHelloTrait {

??????//必须覆盖抽象 field

??????val msg = "Hello"

??????def makeFriends(other: PersonForAbstractField) = {

????????this.sayHello(other.name)

????????println("I‘m " + this.name + ",I want to make friends with you!!")

??????}

????}

????object PersonForAbstractField{

??????def main(args: Array[String]) {

????????val p1=new PersonForAbstractField("Tom")

????????val p2=new PersonForAbstractField("Rose")

????????p1.makeFriends(p2)

??????}

????}

? ?

5、在实例对象指定混入某个trait

  • 可在创建类的对象时,为该对象指定混入某个trait,且只有混入了trait的对象才具有trait中的方法,而其他该类的对象则没有;
  • 在创建对象时,使用 with 关键字指定混入某个 trait;

    举例说明:

????trait LoggedTrait {

??????// 该方法为实现的具体方法

??????def log(msg: String) = {}

????}

????trait MyLogger extends LoggedTrait{

??????// 覆盖 log() 方法

????override def log(msg: String) = println("log: " + msg)

????}

???? ?

????class PersonForMixTraitMethod(val name: String) extends LoggedTrait {

??????def sayHello = {

????????println("Hi,I‘m " + this.name)

????????log("sayHello method is invoked!")

??????}

????}

????object PersonForMixTraitMethod{

??????def main(args: Array[String]) {

????????val tom= new PersonForMixTraitMethod("Tom").sayHello //结果为:Hi,I‘m Tom

????????// 使用 with 关键字,指定混入MyLogger trait

????????val rose = new PersonForMixTraitMethod("Rose") with MyLogger

????????rose.sayHello

????// 结果为:???? Hi,I‘m Rose

????// 结果为:???? log: sayHello method is invoked!

??????}

????}

6、trait 调用链

  • Scala中支持让类继承多个trait后,可依次调用多个trait中的同一个方法,只要让多个trait中的同一个方法,在最后都依次执行 super 关键字即可;
  • 类中调用多个trait中都有的这个方法时,首先会从最右边的trait的方法开始执行,然后依次往左执行,形成一个调用链条;
  • 这种特性非常强大,其实就是设计模式中责任链模式的一种具体实现;

    案例说明:

????trait HandlerTrait {

??????def handle(data: String) = {println("last one")}

????}

????trait DataValidHandlerTrait extends HandlerTrait {

??????override def handle(data: String) = {

??????????????????println("check data: " + data)

??????????????????super.handle(data)

????}

????}

????trait SignatureValidHandlerTrait extends HandlerTrait {

??????override def handle(data: String) = {

??????????????println("check signature: " + data)

??????????????super.handle(data)

??????}

????}

????class PersonForRespLine(val name: String) extends SignatureValidHandlerTrait with DataValidHandlerTrait {

??????def sayHello = {

????????????println("Hello," + this.name)

????????????this.handle(this.name)

??????}

????}

????object PersonForRespLine{

??????def main(args: Array[String]) {

???????? val p=new PersonForRespLine("tom")

??????????p.sayHello

??????????//执行结果:

????//????Hello,tom

????//????check data: tom

????//????check signature: tom

????//????last one

??????}

????}

7、混合使用 trait 的具体方法和抽象方法

  • 在 trait 中,可以混合使用具体方法和抽象方法;
  • 可以让具体方法依赖于抽象方法,而抽象方法则可放到继承 trait的子类中去实现;
  • 这种 trait 特性,其实就是设计模式中的模板设计模式的体现;

    举例说明:

????trait ValidTrait {

???? //抽象方法

??????def getName: String????

????//具体方法,具体方法的返回值依赖于抽象方法

???????????????????????????? ?

???? def valid: Boolean = {"Tom".equals(this.getName)

??????}

????}

????class PersonForValid(val name: String) extends ValidTrait {

??????def getName: String = this.name

????}

???? ?

????object PersonForValid{

??????def main(args: Array[String]): Unit = {

????????val person = new PersonForValid("Rose")

????????println(person.valid)

??????}

????}

? ?

? ?

8、trait的构造机制

  • 在Scala中,trait也是有构造代码的,即在trait中,不包含在任何方法中的代码;
  • 继承了trait的子类,其构造机制如下:
  • 父类的构造函数先执行, class 类必须放在最左边;多个trait从左向右依次执行;构造trait时,先构造父 trait,如果多个trait继承同一个父trait,则父trait只会构造一次;所有trait构造完毕之后,子类的构造函数最后执行。

    举例说明:

????????class Person_One {

??????????println("Person‘s constructor!")

????????}

????????trait Logger_One {

??????????println("Logger‘s constructor!")

????????}

????????trait MyLogger_One extends Logger_One {

??????????println("MyLogger‘s constructor!")

????????}

????????trait TimeLogger_One extends Logger_One {

??????????println("TimeLogger‘s contructor!")

????????}

????????class Student_One extends Person_One with MyLogger_One with TimeLogger_One {

??????????println("Student‘s constructor!")

??????????}

????????object exe_one {

??????????def main(args: Array[String]): Unit = {

????????????val student = new Student_One

????????????//执行结果为:

????????//??????Person‘s constructor!

????????//??????Logger‘s constructor!

????????//??????MyLogger‘s constructor!

????????//??????TimeLogger‘s contructor!

????????//??????Student‘s constructor!

??????????}

????????}

? ?

9、trait 继承 class

  • 在Scala中trait 也可以继承 class,此时这个 class 就会成为所有继承该 trait 的子类的超级父类。

    举例说明:

????????class MyUtil {

??????????def printMsg(msg: String) = println(msg)

????????}

????????trait Logger_Two extends MyUtil {

??????????def log(msg: String) = this.printMsg("log: " + msg)

????????}

????????class Person_Three(val name: String) extends Logger_Two {

????????????def sayHello {

????????????????this.log("Hi,I‘m " + this.name)

????????????????this.printMsg("Hello,I‘m " + this.name)

??????????}

????????}

????????object Person_Three{

??????????def main(args: Array[String]) {

??????????????val p=new Person_Three("Tom")

??????????????p.sayHello

????????????//执行结果:

????????//??????log: Hi,I‘m Tom

????????//??????Hello,I‘m Tom

??????????}

????????}

?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读