学习Scala的二维布局库和抽象类

二维布局库

作为本章运行的例子,我们将创造一个制造和渲染二维布局元素的库。每个元素将代表一个填充字符的长方形。方便起见,库将提供名为“elem”的工厂方法来通过传入的数据构造新的元素。例如,你将能通过工厂方法采用下面的写法创建带有字串的元素:

elem(s: String): Element  

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

正如你所见,元素将以名为Element的类型为模型。你将能在元素上调用above或beside,传入第二个元素,从而得到合并了这两个的新元素。例如,下面的表达式将构建一个包含两列,每列高度为二,的更大的元素:

val column1 = elem("hello") above elem("***")  



val column2 = elem("***") above elem("world")  



column1 beside column2  
打印这个表达式的结果将是:
hello ***  


*** world  
在对象能通过简单的部件及组合操作符的帮助被构建的系统中,布局元素是个好的例子。本章里,我们将定义类使得元素对象能被构建自数组,行记录,以及长方形――简单部件。我们还将定义组合操作符above和beside。这种组合操作符也经常被称为组合子:combinator,因为它们把某些区域的元素组合成新的元素。

以组合子的方式思考问题通常是实现库的设计的好方法:它能回报以考虑在应用域构建对象的基础方法。什么是简单对象?用什么方式能让更多有趣的对象通过简单对象构造出来?组合子是怎么挂在一起的?什么是最通用的组合?它们满足任何有趣的规则吗?如果你对这些问题都有好的答案,你的库设计就在正轨上了。

抽象类

我们的第一个任务就是定义代表布局元素的类型Element。由于元素是二维的字符长方形,包括成员,指向布局元素内容的contents,是合情合理的。内容可以被表达成字串数组,这里每个字串代表一行。因此,contents返回的结果类型就是Array[String]。代码10.1展示了它看起来的样子。

这个类里,contents被声明为没有实现的方法。换句话说,方法是类Element的抽象:abstract成员。具有抽象成员的类本身必须被声明为抽象的,只要在class关键字之前加上abstract修饰符即可:

abstract class Element {  


def contents: Array[String]  


}  
代码 10.1 定义抽象方法和类
abstract class Element ...  
abstract修饰符说明类或许有没实现的抽象成员。结果,你不能实例化抽象类。如果你尝试这么做,你会得到编译器错误:
scala> new Element  



< console>:5: error: class Element is abstract;  



 cannot be instantiated  



 new Element  



 ˆ  
本章后面你会看到如何创建类Element的子类,你将能实例化它们因为它们补上了缺失的contents定义。

请注意类Element的contents方法并没带有abstract修饰符。如果方法没有实现(也就是说,没有等号或方法体),它就是抽象的。不像Java,方法的声明中不需要(或允许)抽象修饰符。拥有实现的方法被称为具体的:concrete

相关推荐