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

除了从父类集成代码外,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类来表示格利高里历中的日期。这个日期由年、月、日三个部分组成,每个部分都可以用一个整数表示。所有我们就得出了下面这个定义:

classDate(y:Int, m:Int, d:Int)extendsOrd{
            def year = y
            def month = m
            def day = d
            overridedef toString():String= year +"-"+ month +"-"+ day
}

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

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

overridedef 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中继承的。




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