浅谈Scala的特质(trait)

三世轮回 提交于 2019-12-07 19:07:30
        虽然scala的特征相当于Java的接口,但是在使用上,我觉得scala的特征更像抽象类。
一个trait 就是把一些共同的性质抽象出来,哪个类需要就混入.

        比如我们要开发一个2D图形库,必然涉及到矩形对象的定义。
一个矩形可以由对角线上的两个端点唯一确定。矩形对象一般具有获取左右边界和获取宽度的方法。不妨定义如下的类:
class Point(val x: Int, val y: Int)  
class Rectangle(val topLeft: Point, val bottomRight: Poit){
    def left = topLeft.x
    def right = bottomRight.x
    def width = rigth - left 
   // more methods
}

考虑到按钮(Button), 文本框(TextBox)等具有“矩形形状”的对象都应该具有left right , width 这些方法,于是我们自然而然会把具有“矩形”特征的操作抽象出来。然而在Java中,这种抽象遇到一点麻烦,如果我们把这几个方法定义在Java接口(interface)中,则每个实现这种接口的类都必须实现接口中的所有方法,事实上这三个方法:left, right,width在大部分的实现类中的默认实现都是雷同的。如果把他们定义在抽象类中,虽然能给出方法的默认实现,但是考虑到Java是单继承的语言,一旦选择继承了某个类,我们也就失去继承其他类的机会了。因此,在Java中,通常的做法是先把方法定义在Java接口中,然后通过定义一些抽象类(这个抽象类可能不止实现了一个接口)来适配它,最终子类只需直接继承这个抽象适配类.

        scala的trait把一切变得简单,我们可以直接在trait中给出left ,right ,width的默认实现,子类如果需要,则直接混入该特征。如果觉得哪个方法“不爽”,就override它。 Scala 的解决方案如下:
triat Rectangular{
   def topLeft: Point
   def  bottomRight: Point
   def left = topLeft.x
   def right = bottomRight.x
   def width = right - left   

   // other methods
}

class Rectangle(private val x: Point, private val y : Point) extends Rectangular{
   // other methods
}

So cool ~~~!

由于trait允许定义具体方法和成员变量,所以无需像Java那样定义很多抽象适配器。如果读者查阅Scala的api文档,就会发现它的集合框架就是按照这种思想设计的,从而赋予Scala集合框架很多强大的功能。
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!