几何形式的多态性

时间:2011-11-30 18:13:36

标签: polymorphism

我正在开发一个小型绘图应用程序,可以拖放一些“复杂”形式的库。

当我从一群其他人那里扩展出大量的物体层次时,我总是怀疑。特别是,我并不总是知道什么是最佳实践,为纯代码压缩目的扩展对象,或者仅在语义上有意义时扩展对象。

这里有一个简单的例子。我有一个带有一个属性的方形对象:edge。然后是一个矩形和许多其他形状。矩形是否应该从正方形延伸,因为它只是添加参数?或者我应该反过来因为square是数学中矩形的特化?两种方式似乎都存在问题。

3 个答案:

答案 0 :(得分:3)

请注意,扩展意味着关系。在你的情况下,制作矩形扩展正方形就像是说“矩形正方形”(就几何而言,它不是必然的)。因此,对于我来说,制作正方形扩展矩形更有意义,因为“正方形矩形”更正确。

一般来说,如果你计划包含“许多其他形状”,似乎在方形或矩形中具有“边缘”属性是很奇怪的。我会建议一个 Polygon 类,它包含一组边,然后是矩形四边形类,它扩展了Polygon,然后可能是 Square Regular四边形类扩展了它。

答案 1 :(得分:2)

乔纳森的答案是最正确的,但考虑只是让一切都变成一个简单的Shape : Polygon关系。从矩形中获取Square有什么收获(如果你确实甚至需要一个Square)?如果没有什么可以获得的,那么就不要这样做。这应该是OOP的第一原则。巨大的类层次结构难以维护,因此您的第一步是确定是否需要这样做。

此外,您似乎对继承的含义感到困惑。继承不仅仅是拥有比父类更多参数或方法的质量,而是根据域规则成为该类的子集的质量。大多数时候会有其他属性,但并非总是如此。就像乔纳森所说,一个矩形在现实生活中不是一个正方形,因此它不能从Square类派生出来。

在您的矩形和方形示例中,您似乎坚持认为Square只有一个参数edge,但是它使widthlength同时保持不变参数,每个都相等?在这种情况下,您可以声明正方形是一个矩形,强制执行相等长度和宽度的规则。这种方式很简单,并且不违反OO。

答案 2 :(得分:0)

即使是非常简单的例子,将继承视为“依存”关系也会失效。

Square是一个矩形?

正如您在问题中指出的那样,正方形看起来像是一种特殊的矩形。这个事实表明矩形应该从正方形继承。但是,请考虑以下代码: -

foo( Rectangle r )
{
  r.setWidth( 5 );
  r.setHeight( 10 );
  print( r.getWidth() );
}

根据您是否传入RectangleSquare的实例,答案会有所不同。 Square无法取代Rectangle。从某种意义上说,square不是一个矩形。向子类添加约束会破坏Liskov Substitution Principle。当子类具有父类中不存在的额外约束时,继承不适合。

矩形是方形?

所以也许Rectangle延伸Square?它就像一个具有额外特殊功能的正方形myWidth可能与myHeight不同?

继承的成员变量myEdgeLength会变成什么?这是多余的,任何使用它可能是一个错误。

程序员出现并向getPerimeter()添加Square方法。因此,Rectangle继承了这一点。它会给出错误的答案。继承没有帮助。

代表

我建议继承在这里根本没用。 Square应该在内部使用矩形。在构造Square时,它会创建自己的Rectangle内部表示,并将其放在成员变量中。

setEdgeLength被调用时,它会调用myRectangle.setWidth( x )myRectangle.setHeigth( x )。调用getArea()时,它会委托给myRectangle.getArea

也可以委派许多其他功能。例如:containsPoint,getPerimiter,重叠等

令人遗憾的是,语言需要样板来进行委派。