Scala开发教程(42): 组合和继承–定义heighten和widen函数

jerry Scala 2015年11月25日 收藏

我们还需要最后一个改进,之前的Element实现不够完善,只支持同样高度和同样宽度的Element使用above和beside函数,比如下面的代码将无法正常工作,因为组合元素的第二行比第一行要长:

  1. new ArrayElement(Array("hello")) above
  2. new ArrayElement(Array("world!"))

与之相似的,下面的表达式也不能正常工作,因为第一个ArrayElement高度为二,而第二个的高度只是一

  1. new ArrayElement(Array("one", "two")) beside
  2. new ArrayElement(Array("one"))

下面代码展示了一个私有帮助方法,widen,能够带个宽度做参数并返回那个宽度的Element。结果包含了这个Element的内容,居中,左侧和右侧留需带的空格以获得需要的宽度。这段代码还展示了一个类似的方法,heighten,能在竖直方向执行同样的功能。widen方法被above调用以确保Element堆叠在一起有同样的宽度。类似的,heighten方法被beside调用以确保靠在一起的元素具有同样的高度。有了这些改变,布局库函数可以使用了

  1. abstract class Element {
  2. def contents: Array[String]
  3. def height: Int = contents.length
  4. def width: Int = if (height == 0) 0 else contents(0).length
  5. def above(that: Element) :Element =
  6. Element.elem(this.contents ++ that.contents)
  7. def beside(that: Element) :Element = {
  8. Element.elem(
  9. for(
  10. (line1,line2) <- this.contents zip that.contents
  11. ) yield line1+line2
  12. )
  13. }
  14. def widen(w: Int): Element =
  15. if (w <= width) this
  16. else {
  17. val left = Element.elem(' ', (w - width) / 2, height)
  18. var right = Element.elem(' ', w - width - left.width, height)
  19. left beside this beside right
  20. }
  21. def heighten(h: Int): Element =
  22. if (h <= height) this
  23. else {
  24. val top = Element.elem(' ', width, (h - height) / 2)
  25. var bot = Element.elem(' ', width, h - height - top.height)
  26. top above this above bot
  27. }
  28. override def toString = contents mkString "\n"
  29.  
  30. }