- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Liskov Substitution Principle 对派生类中的方法签名施加的规则之一是:
Contravariance of method arguments in the subtype.
最佳答案
在这里,按照 LSP 所说的,“派生对象”应该可用作“基础对象”的替代品。
假设您的基础对象有一个方法:
class BasicAdder
{
Anything Add(Number x, Number y);
}
// example of usage
adder = new BasicAdder
// elsewhere
Anything res = adder.Add( integer1, float2 );
class ComplexAdder
{
Complex Add(Complex x, Complex y);
}
// example of usage
adder = new ComplexAdder
// elsewhere
Anything res = adder.Add( integer1, float2 ); // FAIL
integer1, float2
参数,因为它实际上
需要 复杂参数。
Anything
。
class SupersetComplexAdder
{
Anything Add(ComplexOrNumberOrShoes x, ComplexOrNumberOrShoes y);
}
// example of usage
adder = new SupersetComplexAdder
// elsewhere
Anything res = adder.Add( integer1, float2 ); // WIN
class SmartAdder
{
Anything Add(Anything x, Anything y)
{
if(x is not really Complex) throw error;
if(y is not really Complex) throw error;
return complex-add(x,y)
}
}
How Contravariance rule is helpful in achieving data/procedure abstraction?
很好……对我来说很明显。如果您创建组件,这些组件是可交换/可交换/可替换的:
BASE:天真地计算发票总和 DER-1:并行计算多个内核上的发票总和 DER-2:使用详细日志记录计算发票总和
然后添加一个新的:
计算不同币种发票的总和
并假设它处理欧元和英镑输入值。旧货币的投入怎么样,比如美元?如果你忽略它,那么新组件 不是 替换旧组件。您不能只是取出旧组件并插入新组件并希望一切正常。系统中的所有其他事物仍可能会发送美元值作为输入。
如果我们创建从 BASE 派生的新组件,那么每个人都应该安全地假设他们可以在之前需要 BASE 的任何地方使用它。如果某个地方需要 BASE,但使用了 DER-2,那么我们应该能够在那里插入新组件。这是 LSP。如果我们不能,那么某些东西就坏了:
任何一个使用地点都不需要 BASE 但实际上需要更多 或我们的组件确实 不是 BASE (请注意 is-a 措辞)
现在,如果没有任何问题,我们可以用一个替换另一个,无论是美元还是英镑,还是单核还是多核。现在看上一层的大图,如果不再需要关心具体的货币种类,那么我们成功抽象出来大图会更简单,当然,组件需要内部处理不知何故。
如果这对数据/过程抽象没有帮助,那么看看相反的情况:
如果派生自 BASE 的组件不遵守 LSP,那么当美元合法值到达时,它可能会引发错误。或者更糟的是,它不会注意到并将它们作为英镑处理。我们出现了问题。为了解决这个问题,我们需要要么修复新组件(以遵守 BASE 的所有要求),要么更改其他相邻组件以遵循新规则,例如“现在使用 EUR 而不是 USD,否则 Adder 将抛出异常”,或者我们需要添加一些东西到大局来解决它,即添加一些分支来检测旧式数据并将它们重定向到旧组件。我们只是将复杂性“泄露”给了邻居(也许我们强制他们破坏了 SRP),或者我们使“大局”更加复杂(更多的适配器、条件、分支……)。
关于contravariance - 为什么 Liskov 替换原则需要参数是逆变的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40340317/
假设我们有这个非常简单的类: class A { virtual int Function(int number) { return number; } } cla
我在学习liskov substitution principle .它说 sub classes should be proper replacement for the base classes
松散地说,里氏替换原则指出派生类可以替代基类而不影响用户。 如果基类是抽象类,即没有用户使用基类的实例,那么 Liskov 继承限制是否仍然适用于派生类? 最佳答案 仅仅因为你不能实例化一个特定的类并
我想了解 Liskov 替换原则。但我无法确定 Liskov 替换原则与正常继承有何不同。下面的代码是关于普通继承的。我应该如何处理下面的代码才能说我的代码遵循 Liskov 替换原则 pub
此问题是 this 的后续问题.我正在尝试定义涉及多个基派生对的类层次结构。作为说明性示例,假设我有一个类 Animal 和一个类 Food。 Animal 有一个纯虚函数来标记它的食物偏好,以食物为
在我的游戏中我定义了一个 Screen类,其中包含对多个视觉对象的引用 Entity可能被绘制到显示器上的对象: class Screen { public: private: std::vect
假设我有这样一个类: public sealed class Foo { public void Bar { // Do Bar Stuff } } 我想扩展它以
我遇到了 Liskov 替换原则的问题,我不太确定解决它的最佳方法是什么。 有问题的代码 class BaseModel: def run(self, base_model_input: Ba
我只是想知道 IS-A(即 UML 术语和 OOP)和 Liskov 替换原则(LSP)之间是否有区别? 实际上,两者都在谈论继承。那么在实践中的主要区别是什么? 最佳答案 这两个术语最终都描述了相同
Liskov Substitution Principle 对派生类中的方法签名施加的规则之一是: Contravariance of method arguments in the subtype.
我试图理解 里氏代换原理 ,我有以下代码: class Vehicle { } class VehicleWithDoors extends Vehicle { public void ope
我正在设计一个订单系统,状态设计模式似乎很合适,因为订单可以更改其状态,从而更改订单允许的功能。下面是我的基本类图: 我不喜欢这种方法,因为客户端无法查看某个方法是否受支持并且违反了里氏原则。我在下面
今天有人问我里氏代换原则与开闭原则有何冲突,有什么想法吗? 是不是跟用OC原理扩展父类,然后用里氏原理不能介入替代有关系吗? 最佳答案 假设您有一个包含具有某些功能的类 A 的库,并且您想要更改此类(
我有两个数据模型,它们由以下类表示: 1) ImagesSet - 拥有2DImage的对象,每个2DImage都有自己的位置(原点(3DPoint), x-,y-axes(3DVector) 以及沿
我对 SOLID 设计原则很陌生。我在理解上遇到问题的一件事是违反 Liskov 替换原则的“方形矩形”示例。为什么正方形的高度/宽度 setter 应该覆盖矩形的 setter ?当存在多态时,这不
假设一个名为 Sprinter 的类: public class Sprinter { protected int travelMeters; public void run(int
LSP 是 SOLID 中最难正确理解的。 LSP 声明程序中的对象应该可以用它们的子类型的实例替换,而不会改变程序的正确性。 因此,如果我们有这个典型的矩形 - 正方形示例: rect = new
ICollection.Add() - 数组的实现打破了 Liskov 替换原则?该方法导致 NotSupportedException ,这确实打破了 LSP,恕我直言。 string[] data
Java 不允许Collection作为 Collection 的子类型.这是因为 Collection不能代替每个 Collection作为 Collection可能包含其他 Vehicle 子类型
我想提出一个面向对象的设计,但很难满足里氏替换原则。这是一个说明性示例: class Food { public: virtual void printName() { //.
我是一名优秀的程序员,十分优秀!