gpt4 book ai didi

software-design - 打破里氏替换原则

转载 作者:行者123 更新时间:2023-12-05 01:40:53 26 4
gpt4 key购买 nike

我有以下代码

public class A 
{
public double foo(double y)
{
return real_value;
}
}

foo 的输入方法 -1 < y < 1函数的结果是一个大于零的实数。

然后我继承了class B继承了 class A并覆盖方法 foo .

public class B extends A 
{
public override double foo(double y)
{
return real_value;
}
}

foo 的输入方法 0 < y < 1函数的结果是任何实数。

这里是否违反了里氏替换原则?

提前致谢。

最佳答案

假设,你想在你的程序中使用 B 作为 A 的子类型:
是的,您的代码明显违反了 LSK。

为什么?
参数应该是逆变的。

这是什么意思?
Liskov Principle 确保,如果您的子类型 B 被基本类型 A 替换,您的程序的行为不会发生变化。

或更准确地说(作者:Barbara Liskov,1987 年):

“If for each object o1 of type B there is an object o2 of type A
such that for all programs P defined in terms of A, the behaviour of P is unchanged
when o1 is substituted for o2, then B is a subtype of A”.

例如:

   class Duck               { void fly(int   height) {} }
class RedheadDuck : Duck { void fly(long height) {} }
class RubberDuck : Duck { void fly(short height) {} }

class LSPDemo
{
public void Main()
{
Duck p;

p = new Duck();
p.fly(int.MaxValue); // Expected behaviour

p = new RedheadDuck();
p.fly(int.MaxValue); // OK

p = new RubberDuck();
p.fly(int.MaxValue); // Fail
}
}

=> the program behaves unchanged, if the argument is contravariant.
=> e.g. base type <= sub type
=> RubberDuck violates this principle, as it does not allow all values of the base type Duck

在您的代码中,基类 A foo 的类型期望参数值为 -1 < y < 1
您的子类 B foo 期望参数值 0 < y < 1
如果您的程序将子类替换为基类,则您的程序对于 foo 的值 <= 0 的行为将不会像预期的那样。

编辑:虽然您在两个 foo 方法上都使用 double 作为参数类型,但我假设您通过检查值及其范围来保护您的方法。这将导致所描述的失败,类似于示例。

P.S.:是的,这取决于您为 foo 定义的契约。假设你想使用 B 作为 A 的子类型,那么它违反了 LSK。否则它只是一个方法覆盖。

关于software-design - 打破里氏替换原则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55606628/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com