[转帖]Scala的Trait:可以包含代码的接口_Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3199 | 回复: 0   主题: [转帖]Scala的Trait:可以包含代码的接口        下一篇 
刘伟
注册用户
等级:少校
经验:938
发帖:82
精华:0
注册:2013-6-24
状态:离线
发送短消息息给刘伟 加好友    发送短消息息给刘伟 发消息
发表于: IP:您无权察看 2013-7-2 8:57:45 | [全部帖] [楼主帖] 楼主

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 的应用远不止于此,不过更加深入的讨论不再本文的讨论范围内。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论