我们为解决方案提供了一系列的UML类图,这些解决方案是用C++或者Java编写的。这些图非常有用,能够帮助我们更好地理解那些利用了类继承和多态的代码。图3-3包含了一个小小的类图,图中展现的是一个超类Segment Tree Node和两个子类,DefaultSegmentTreeNode和StoredIntervalsNode的关系,这两个子类使用继承的方法扩展SegmentTreeNode(箭头指向的类)。每一个类匣有两个部分:上部列出了实例变量,下部列出了实例方法。每个属性或者方法名称前的符号是非常重要的。
图 3-3 UML图样例#(protected)
声明这个方法或者属性只对这个类或者其子类可见;如果是使用Java实现的话,那么这个方法或者属性只对在同一个包中的类可见。注意在C++实现中,我们不会使用多重继承或者友元,所以在本书的这两种语言实现中,这个语法是相同的。
~(package-private)
声明这个属性或者方法只对同一个包内的类可见,只在Java中使用。
-(private)
声明这个属性只对定义了这个属性的类本身可见。我们没有在类图中列出任何可能存在的私有方法。
+(public)
声明这个属性或者方法对任何类可见,并能被任何类存取。公共属性一般来说都会用"final"修饰,表示它们即使在相同的类中,也都是常量。
类方法都会声明返回类型(有可能是void)以及参数列表(也可能是空的)。构造器的名称和定义这个构造器的类名相同。析构器(仅仅在C++)能够很容易地从其名称前的“~”辨识出来。当然,读者也许会混淆C++的析构器和Java的package-private方法,因为它们使用了相同的符号。看看算法章节中的附带文字,这些能够帮助你区分这两种情形。
在Java中,类和类实现的接口之间有一种特殊的关系。例如,如果SegmentTreeNode实现了IInterval,那么SegmentTreeNode必须实现IInterval中的方法。这种关系在图3-3中用一个带箭头的细虚线描述出来。