datatype Triangle as Polygon{
check:
lines.size()==3;
}
这样的判断,其实是有漏洞的。假设多边形中,有一条以上的直线,长度为0,那么这个多边形,就不是一个三角形了。因此,我们需要修改Line的类型定义:
datatype Line{
Point p1;
Point p2;
check:
length(this)>0;
checkMethods:
double length(this){
}
}
OK,有了这样的Line以后,我们得到的三角形、四边形就是正确的了。
让我们接着看看,怎么定义:等腰三角形、直角三角形、正三角形、等腰直角三角形。
datatype IsoscelesTriangle as Triangle{
check:
length(this.item(0))==length(this.item(1))||length(this.item(1))==length(this.item(2))||length(this.item(0))==length(this.item(2));
checkMethods:
double length(Line line){
return Line.length(line);
}
}
length原本是定义在Line里的一个检查方法,这个方法,等腰三角形并不能直接使用,因为IsoscelesTriangle并没有继承Line。
datatype EquilateralTriangle as IsoscelesTriangle{
check:
length(this.item(0))==length(this.item(1));
length(this.item(1))==length(this.item(2));
}
因为EquilateralTriangle as IsoscelesTriangle,因此不需要再次定义length了。
datatype RightTriangle as Triangle{
check:
(isRightAngled(this.item(0),this.item(1))||isRightAngled(this.item(1),this.item(2))||isRightAngled(this.item(0),this.item(2));
checkMethods:
boolean isRightAngled(Line line1,Line line2){
}
}
这个应该不难理解。接下来定义最后一个“OO面临的多重继承难题”。
datatype IsoscelesRightTriangle as IsoscelesTriangle,RightTriangle{
}
没了?是啊,就这么简单,定义等腰直角三角形,成了最简单的部分了。
下面说说这个数据类型定义的原理吧。在我看来,所谓数据类型,就是符合一系列逻辑判断条件的数据。一个数据,如果符合三角形的判断条件,那么它就是三角形,如果它同时符合等腰和直角的两组——注意:是两组,而非两个——判断条件,那么他就是等腰直角三角形。
如果我们将正三角形的定义改以下:
datatype EquilateralTriangle as Triangle{
check:
length(this.item(0))==length(this.item(1));
length(this.item(1))==length(this.item(2));
}
它还是个等腰三角形吗?当然,因为符合正三角形判定条件的三角形,可能可以通过等腰三角形的check。所以,其实所有的数据类型之间,并没有任何关系,他们之间的那个as,只是为了解决check代码的复用需要,任何数据,只要能够通过某一类型的check,那么它就实质上属于那一类型。就这么简单,无歧义。大家以为如何?
(未完待续)