`
tongqingqiu
  • 浏览: 24803 次
  • 性别: Icon_minigender_1
  • 来自: 亚特兰大
社区版块
存档分类
最新评论

Scala基础(7)- 特质

阅读更多

特质是Scala中一个很重要的特性。

更灵活的接口

Scala的特质(trait)定义和class几乎相同,只是trait不能的构造不能包含参数。

  trait TraitClassA {
    def doSomething() {
       println("call A");
    }
}

  trait TraitClassB {
    def doSomething() {
        println("call B");
    }
}

在使用trait的时候,可以用extend或者withwith的方式成为混入(mixin)。用户可以with任意多个特质。这会让你想起接口(Interface)。

  class A extends B with TraitClassA with TraitClassB {
          ...
}

Trait可以看做是更灵活,更丰富的接口。和Java中接口不同的是,Trait可以包含成员和方法的实现。这样做的好处需要某个trait就拿来用,而不需要重复实现接口。trait和混入的类是正交的。

举例说明,在Java中,定义一个Rational类就需要重写多个比较的方法。

class Rational(n: Int, d: Int) {
          // ...
          def < (that: Rational) =
            this.numer * that.denom > that.numer * this.denom
          def > (that: Rational) = that < this
          def <= (that: Rational) = (this < that) || (this == that)
          def >= (that: Rational) = (this > that) || (this == that)
}

而如果使用trait,这些比较的方法就可以封装在Ordered这个特质中(注意到这里使用到了类型参数[Rational])。以后所有需要实现比较特质的类,它只要实现compare方法。

class Rational(n: Int, d: Int) extends Ordered[Rational] {
    // ...
    def compare(that: Rational) =
      (this.numer * that.denom) - (that.numer * this.denom)
}

而在使用的时候,你还是可以使用><=这样的方法,因为它们已经在Ordered特质中得到了实现。

值得注意的是,Java8中也借鉴了类似的方式。现在你可以在Java的接口中定义默认的实现了。但是它的限制还是很多。对于Java8一些新特性和Scala的比较,今后会专门讲。

堆叠和线性化

在下面的例子里,我们定义了带时间戳的日志和截断过长的的日志,这两个特质。

// 带时间戳的日志
trait TimestampLogger extends Logged {
  override def log (msg: String) {
    super.log(new java.util.Date() + " " + msg)
  }
}

// 截断过长的的日志

trait ShortLogger extends Logged {
  val maxLength = 20
  override def log(msg: String) {
    super.log(
      if (msg.length <= maxLength) msg
      else msg.substring(0, maxLength - 3) + "...")
  }
}

我们的应用就可以混入这两个特质。

class myApp with TimestampLogger with ShortLogger

你也许觉得trait和C++中的多继承很像。但是它们有着根本的区别。在多继承的框架里,你必须指定哪个super被调用(比如通过虚函数)。这样,在上面的例子中,只有一个log方法会调用。而trait恰恰可以堆叠多个特性,每个log都会被调用。这才符合多个特质的语义。

注意到混入是有顺序的,基本上可以认为是最右边的先调用。在更复杂的情景中,Scala使用了线性化的方式,将复杂的继承图映射到一条线上,以保障多个特质执行的顺序。

使用原则

什么时候使用特质呢?

  • 不需要复用的,或者执行效率非常关键,考虑使用具体类。
  • 会在多个不太相关的类中使用,考虑使用特质。
  • 继承自Java的代码,或者希望Java client以后调用,使用抽象函数。
  • 不太确定使用哪种方式,考虑先使用特质,以后再调整。

使用特质的一个重要原则就是保持traits简短并且是正交的。不要把分离的功能混在一个trait里,考虑将最小的相关的意图放在一起。例如,想象一下你要做一些IO的操作:

trait IOer { 
    def write(bytes: Array[Byte]) 
    def read(n: Int): Array[Byte] 
}

分离两个行为:

trait Reader { def read(n: Int): Array[Byte] } 
trait Writer { def write(bytes: Array[Byte]) }

可以将它们以混入的方式实现一个

IOer : new Reader with Writer...

接口最小化促使更好的正交性和更清晰的模块化。

0
0
分享到:
评论

相关推荐

    Scala-2.11.1.zip

    Scala这个名字是“Scalable Language”的缩写,它旨在克服Java的一些局限性,同时保留其平台兼容性和面向对象的基础。 在Scala-2.11.1.zip这个压缩包中,我们看到的是Scala的特定版本2.11.1。这个版本是在Scala 2.x...

    scala-sbt-helloworld.zip

    通过以上步骤,你已经成功地在VSCode中创建了一个基础的Scala-SBT-Helloworld项目。随着你对Scala和sbt的理解加深,可以尝试扩展项目,添加更多的功能,或者创建自己的sbt构建脚本来满足特定需求。学习Scala不仅意味...

    scala-docs-2.11.1.zip

    类和对象是构建Scala程序的基础,而特质(trait)则提供了一种灵活的继承和复用机制。函数在Scala中是第一等公民,可以作为值传递,存储在变量中,甚至作为其他函数的参数或返回值。 `2.11.1`是Scala的一个重要版本...

    scala-doc-2.11.8 原版

    1. **基础语法**:Scala的基础语法与Java有很多相似之处,但也有其独特的特点,如模式匹配、高阶函数、类型推断和case类。文档会详细解释这些概念,帮助初学者快速上手。 2. **类型系统**:Scala有一个强大的静态...

    scala sdk scala-2.12.3

    2. **标准库**:Scala的标准库提供了大量的类和模块,包括集合操作、I/O、反射、并发处理等,这些是编写Scala程序的基础。 3. **Scala REPL**:Read-Eval-Print Loop,交互式解释器,允许开发者即时测试代码片段,...

    scala-423-n

    7. Scala REPL(Read-Eval-Print Loop):Scala提供了交互式的命令行工具,允许开发者快速测试代码片段,加速开发过程。 8. Akka框架:虽然不是Scala语言的一部分,但Akka是一个在Scala中广泛使用的并发和分布式...

    scala-2.13.8 解压安装版

    4. **库和框架**:Scala是许多流行框架的基础,如Play Framework(用于Web开发)、Apache Spark(大数据处理)和Akka(并发和分布式计算)。这些框架使得开发高效、可扩展的应用变得容易。 5. **编译器和IDE支持**...

    快学Scala完整版&Scala编程(中文版)&Scala程序设计-多线程编程实践

    它可能涵盖了变量声明、基本数据类型、类与对象、模式匹配、高阶函数、类型系统、特质(trait)等主题,这些都是Scala编程的基石。此外,这本书还可能深入到Akka框架的介绍,因为Akka是Scala中用于构建分布式、反应...

    大数据课程-Scala编程基础-3.Scala面对对象的特性_lk_edit.ppt

    本节主要讲解Scala在面向对象编程方面的特性,包括包管理、类和对象、单例对象和伴生对象、特质、枚举类以及应用类。 首先,Scala的包管理类似于Java,用于组织和管理类,避免名称冲突并提供访问控制。包的命名遵循...

    scala-2.7.5.final

    7. **命令行工具**:除了编译器和解释器,Scala还提供了用于构建、测试和文档生成的工具,如sbt(Scala Build Tool)的前身。 总结来说,"scala-2.7.5.final" 包含了Scala语言的文档、安装程序和核心库,为开发者...

    图灵书籍(Scala程序设计(第2版).pdf+Scala程序设计-JAVA虚拟机多核编程实战.pdf)

    7. **Scala与大数据**:Scala在Apache Spark等大数据框架中的应用,以及如何使用Scala进行大数据处理和分析。 这些知识点不仅涵盖了Scala语言的基础和高级特性,还深入到利用Scala进行JVM平台上的多核并行计算,为...

    scala-2.12.6.tgz

    Scala还引入了一些独特的语言特性,如特质(Traits)、隐式转换和case类,这些帮助开发者实现更简洁、更具表达力的代码。 10. 社区与文档: Scala有一个活跃的社区,提供了丰富的开源库和工具,以及详尽的官方...

    scala-2.13.2.zip

    在学习Scala时,开发者还需要了解一些关键概念,比如 Trait(特质),它是Scala中的一个抽象类的变种,可以用于实现多重继承和代码重用。还有 implicits(隐式转换),它可以帮助解决类型转换的繁琐问题,同时也可...

    Scala语言规范-v2.7.rar

    Spark是一个分布式计算框架,最初就是用Scala编写的,因此Scala是理解和开发Spark应用的基础。Spark利用Scala的高阶函数和弹性数据结构,使得数据处理变得高效且易于编写。Spark支持批处理、交互式查询(Spark SQL)...

    scala-2.10.6.tgz

    - **面向对象**:Scala支持类、对象和继承,同时也引入了特质(trait),提供了一种更灵活的实现多继承的方式。 - **函数式编程**:Scala内置了高阶函数和不可变数据结构,使得函数式编程风格成为可能,这对于并行...

    Scala 编程中文版-前13章

    - **继承**:Scala支持单一继承,但可以通过特质(trait)实现多重继承的效果。 - 继承层次图:通过图释11.1展示了Scala中的类继承层次。 - 类型线性化:通过表格12.1展示了类型在继承链中的线性化顺序。 #### 六、...

    Scala基础.pdf

    1. 面向对象:Scala中的所有值都是对象,它使用类和特质(trait)来定义类和对象的行为,使其成为一个纯面向对象的语言。 2. 函数式编程:Scala支持函数式编程范式,其中函数被当作一等公民(first-class citizens...

    Scala-学习资料-mht.rar

    7. Play框架:Play是一个基于Scala和Java的现代Web应用框架,它采用 Reactive Model(响应式模型)设计,非常适合开发RESTful API和实时Web应用。 8. Spark框架:Apache Spark是大数据处理领域的热门框架,其核心...

    Scala 2.11-API.chm

    在API方面,Scala的基础库非常丰富,包含了许多核心类和特质。例如,`Any`, `AnyVal`, 和 `AnyRef` 是所有Scala类型的根,`AnyVal` 包括原始类型如`Int`, `Double`, `Char`等,而`AnyRef` 类似于Java中的`Object`,...

    scala-fp-book

    1. **基础语法**:Scala的基础语法包括类、对象、特质、模式匹配等,这些都是函数式编程的重要工具。例如,特质(Traits)可以用于实现行为的多继承,模式匹配则提供了强大的数据解构能力。 2. **高阶函数**:Scala...

Global site tag (gtag.js) - Google Analytics