Scala的Trait:可以包含代码的接口

本文源自Michel Schinz和Philipp Haller所写的A Scala Tutorial for Java programmers,由Bearice成中文。第一篇为Scala简单做了一下入门,第二篇描述Scala对象,第三篇对Scala类做了一些介绍。第四篇介绍了Scala的模式匹配。下面这部分介绍Scala的Trait,直译过来就是特性/特征的意思。

为红旗等地区用户提供了全套网页设计制作服务,及红旗网站建设行业解决方案。主营业务为成都网站建设、网站建设、红旗网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

编辑推荐:Scala编程语言专题

7 Scala Trait

除了从父类集成代码外,Scala中的类还允许从一个或者多个traits中导入代码。

对于Java程序员来说理解traits的最好方法就是把他们当作可以包含代码的接口(interface)。在Scala中,当一个类继承一个trait时,它就实现了这个trait的接口,同时还从这个trait中继承了所有的代码。

让我们通过一个典型的实例来看看这种trait机制是如何发挥作用的:排序对象。能够比较若干给定类型的对象在实际应用中是很有用的,比如在进行排序时。在Java语言中可以比较的对象是通过实现Comparable接口完成的 。在Scala中我们可以通过吧Comparable定义为trait来做的比Java好一些。我们吧这个trait叫做Ord。

在比较对象时,一下六种关系通常使用率最高:小于、小于等于、等于、不等于、大于等于、大于。但是把他们都定义一次无疑是很没用而且繁琐的。尤其是六种关系中的四种其实是可以通过其他两种关系导出的。例如给定等于和小于的定义后就可以推导出其他的定义。于是在Scala中,这些推导可以通过下面这个trait实现:

trait Ord {
        def < (that: Any): Boolean
        def <=(that: Any): Boolean = (this < that) || (this == that)
        def > (that: Any): Boolean = !(this <= that)
        def >=(that: Any): Boolean = !(this < that)
}

这个定义在建立了一个叫做与Java中的 Comparable 等效的叫做 Ord的类型的同时还实现了使用抽象的一种关系推导其他三种的接口。比较相等性的方法没有出现是由于他已经默认存在于所有对象中了。

上面使用的叫做Any的类型表示了Scala中所有类的共同超类。事实上它就等于Java语言中的Object。

要使的一个类可以被比较,就需要可以比较他们是否相等或者大小关系,而这些都混合在上面的类Ord中了。现在我们来写一个Date类来表示格利高里历中的日期。这个日期由年、月、日三个部分组成,每个部分都可以用一个整数表示。所有我们就得出了下面这个定义:

class Date(y: Int, m: Int, d: Int) extends Ord {
        def year = y
        def month = m
        def day = d
        override def toString(): String = year + "-" + month + "-" + day
}

注意在类名后出现的extends Ord。这表示了这个类继承了Ord这个trait。

然后我们重新定义了equals这个从Object继承来的方法,好让他能够正确的比较我们日期中的每个部分。原来的equals函数的行为与Java中的一样,是按照对象的指针进行比较的。我们可以得出下面的代码。

override def equals(that: Any): Boolean =
that.isInstanceOf[Date] && {
        val o = that.asInstanceOf[Date]
        o.day == day && o.month == month && o.year == year
}

这个函数使用了预定义函数 isInstanceOf 和asInstanceOf 。第一个isInstanceOf 类似Java中的 instanceof :当且仅当对象是给定类型的实例时才返回true。第二个 asInstanceOf 对应Java中的类型转换操作:当对象是给定类型的子类时转换,否则抛出ClassCastException。

最后我们还需要定义测试小于关系的函数,如下面所示。这个函数使用了预定义的函数error ,它可以使用给定字符串抛出一个异常。

def <(that: Any): Boolean = {
        if (!that.isInstanceOf[Date])
                error("cannot compare " + that + " and a Date")
        val o = that.asInstanceOf[Date] (year < o.year) ||
                (year == o.year && (month < o.month ||
                (month == o.month && day < o.day)))
}

以上就是Data的完整定义了。这个类的实例既可以作为日期显示,也可以进行比较。而且他们都定义了6种比较操作:其中两种 : equals和< 是我们直接定义的,而其他的是从Ord中继承的。

Scala Traits 的应用远不止于此,不过更加深入的讨论不再本文的讨论范围内。

下一篇文章将是这个介绍的最后一部分,讲述Scala的泛型。

【相关阅读】

  1. Scala的模式匹配和条件类
  2. Scala类:复数类,无参方法,继承和覆盖
  3. 万物皆对象:介绍Scala对象
  4. Scala入门:Scala例子,以及如何与Java交互
  5. Scala开发环境搭建与资源推荐

网站标题:Scala的Trait:可以包含代码的接口
URL标题:http://www.mswzjz.com/qtweb/news24/195424.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联