在不违反替代原则的情况下,我很难理解前置条件和后置条件是如何工作的。那么,让我们假设我们有一个类Rectangle
和Square
——如何将它们联系起来?哪个必须是子类?
因此,我假设Subtype
的前置条件可以较弱,这意味着我们可以在子类中取一个主要的"集合",另一方面,后置条件可以更强,这样我们就可以返回一个次要的东西"集合"。如何在我的示例中应用这些规则?
我读到基类必须比子类做得少,所以我认为Square
必须是我们的基类,Rectangle
必须是子类。因此,Square
中的前置条件必须断言为height == width
,但Rectangle
中的后置条件和前置条件呢?
查找超类和子类的通用方法,基本上需要回答以下问题:
每个X都是Y吗?
在你的情况下,你需要说这两件事:
- 每个
Rectangle
都是Square
吗否 - 每个
Square
都是Rectangle
吗是的
因此CCD_ 13是CCD_。那么成为Square
的条件是:
- 如果它是一个矩形和
- 高度等于宽度
实际上情况正好相反。正方形是矩形的一个子类。为什么?每个正方形都是矩形,但不是每个矩形都是正方形。
您可以进一步扩展这种继承关系,每个GeometricShape都是Object,每个Polygon都是GeometricShip,每个Quadrangle都是Polygon,每个Rectangle都是Quadraangle,等等。继承层次越往下走,添加的约束就越多,使子类比父类更特殊。
什么是矩形的边界?每个角都有一个矩形(90°),正方形的约束是什么?它是一个矩形(90°),每条边都有相同的长度。
你需要理解每个正方形都是矩形,但每个矩形都不是正方形。
矩形需要的条件是它有4个大小,不小于不大于,任何三个角度都是90度。
在代码中,它们应该是两个不同的类。我还没有定义多边形类,但你已经了解了它的概念
例如:
public class Quadrilateral extends Polygon {
...
}
下一篇:
public class Rectangle extends Quadrilateral {
private double length;
private double breadth;
public Rectangle (double len, double brd ) {...}
}
然后平方:
public class Square extends Rectangle {
private double side;
public Square (double sideLength) {
super(sideLength, sideLength);
}
}
子类型
子类或子类总是基类或超类的特殊类型。
Java使用关键字extends
,因为子类实际上扩展了超类,经常添加功能。
正方形是一种特殊的,也就是说,更具体的类型的矩形。它是一个矩形,但具有高度等于宽度的附加特性。
利斯科夫替代原理
然而,替换原则——我猜你的意思是Liskov替换原则——规定,在任何你期望某个类(在我们的例子中为Rectangle
)的地方,你都应该能够使用该类的子类型(在我们例子中为Square
),而不会破坏功能或逻辑。如果你不这样做,这个设计就违反了利斯科夫隐性原则。
我可以举一个例子,但这个答案已经写了。请注意,这个答案使用了您提到的类。
因此,总的来说,正方形是矩形的特殊类型听起来很合乎逻辑,但根据利斯科夫替代原理,这是一个糟糕的抽象。
因此,是的,将Square
声明为Rectangle
的子类会使Liskov替换原则失效。
注意,他们还在维基百科上写了一个关于它的页面。这是一个非常常见的问题
- 矩形是正方形的子类。原因是,矩形是一个较弱的正方形的形式:它有较弱的先决条件
- 方形前提条件:四条边,所有边都以90度邻接,所有边相等
- 矩形只有前两个先决条件。这两个人的行为会一样吗客户端代码?是的
- Square:getArea(){return side*side}
- 矩形:
- getArea(){return l*w}<lt;相同的接口Square构造函数:
- 方形(内侧)矩形构造函数1:
- 矩形(内侧){l=side;w=side;}<lt;与正方形相同的界面
- 矩形构造函数2:
- 矩形(int l,int w){this.l=s;this.w=w}<lt;新增
- 为什么矩形可以有一个额外的构造函数?因为它延伸成正方形,因此可以添加功能性,但不能约束超类的功能性