开发手册 欢迎您!
软件开发者资料库

Scala - 特征

Scala Traits - 从简单和简单的步骤学习Scala,从基本到高级概念,包括Scala语法面向对象语言,特征,方法,模式匹配,元组,注释,指示符,概述,环境设置,基本语法,数据类型,变量,类和对象,访问修饰符,运算符,IF ELSE,循环语句,函数,闭包,字符串,数组,集合,正则表达式,异常处理,提取器,文件I / O.

特征封装了方法和字段定义,然后可以通过将它们混合到类中来重用它们.与类继承不同,其中每个类必须只从一个超类继承,一个类可以混合任意数量的特征.

特征用于通过指定支持的特征来定义对象类型方法. Scala还允许部分实现特征,但特征可能没有构造函数参数.

特征定义看起来就像一个类定义,除了它使用关键字 trait .以下是特质的基本示例语法.

语法

trait Equal {   def isEqual(x: Any): Boolean   def isNotEqual(x: Any): Boolean = !isEqual(x)}

此特征包含两种方法 isEqual isNotEqual .在这里,我们没有给出isEqual的任何实现,而另一种方法有其实现.扩展特征的子类可以为未实现的方法提供实现.因此,特征与我们在Java中的抽象类非常相似.

让我们假设一个特征等于的示例包含两个方法 isEqual() isNotEqual().特征等于包含一个 isEqual()的实现方法,因此当用户定义的类 Point 扩展特征时等于 ,应该提供 Point 类中 isEqual()方法的实现.

这里需要知道Scala的两个重要方法,在以下示例中使用.

  • obj.isInstanceOf [Point] 要检查obj和Point的类型不相同.

  • obj.asInstanceOf [Point] 表示通过取对象obj类型进行精确投射并返回与Point类型相同的obj.

尝试以下示例程序来实现特征.

示例

trait Equal {   def isEqual(x: Any): Boolean   def isNotEqual(x: Any): Boolean = !isEqual(x)}class Point(xc: Int, yc: Int) extends Equal {   var x: Int = xc   var y: Int = yc      def isEqual(obj: Any) = obj.isInstanceOf[Point] && obj.asInstanceOf[Point].x == y}object Demo {   def main(args: Array[String]) {      val p1 = new Point(2, 3)      val p2 = new Point(2, 4)      val p3 = new Point(3, 3)      println(p1.isNotEqual(p2))      println(p1.isNotEqual(p3))      println(p1.isNotEqual(2))   }}

将上述程序保存在 Demo.scala 中.以下命令用于编译和执行该程序.

命令

\>scalac Demo.scala\>scala Demo

输出

  true  false  true

价值类别和通用特征

价值类别是Scala中的新机制,以避免分配运行时对象.它包含一个主构造函数,只有一个 val 参数.它仅包含方法(def),不允许使用var,val,嵌套类,特征或对象.值类不能由另一个类扩展.这可以通过使用AnyVal扩展您的值类来实现.自定义数据类型的类型安全性,没有运行时开销.

让我们举一个值类,权重,高度,电子邮件,年龄等的示例.对于所有这些示例,不需要分配内存在应用程序中.

不允许扩展特征的值类.为了允许值类扩展特征,引入了通用特征,其扩展为任何.

示例

trait Printable extends Any {   def print(): Unit = println(this)}class Wrapper(val underlying: Int) extends AnyVal with Printableobject Demo {   def main(args: Array[String]) {      val w = new Wrapper(3)      w.print() // actually requires instantiating a Wrapper instance   }}

将上述程序保存在 Demo.scala .以下命令用于编译和执行该程序.

命令

\>scalac Demo.scala\>scala Demo

输出

它将为您提供哈希码of Wrapper class.

  Wrapper @ 13

何时使用特征?

没有确定的规则,但这里有一些指导要考虑 :

  • 如果不再使用该行为,则将其设为具体类.毕竟,这不是可重复使用的行为.

  • 如果它可能在多个不相关的类中重用,请将其作为特征.只有特征可以混合到类层次结构的不同部分.

  • 如果你想在Java代码中继承,请使用一个抽象类.

  • 如果您计划以编译形式分发它,并且您希望外部组编写从其继承的类,您可能倾向于使用抽象类.

  • 如果效率非常重要,请倾向于使用课程.