gpt4 book ai didi

oop - 当方法有可选参数时,如何不违反 Liskov 替换原则?

转载 作者:行者123 更新时间:2023-12-03 02:57:07 25 4
gpt4 key购买 nike

我在程序中遇到了一个设计问题,原因是 abstract 基础 class 有一个方法和一个位置(因此是可选的)参数。

假设这个类是A,方法是void f(x, [y]);。现在,y 是可选的,因为我已经知道 A 的一些子类会使用它,而有些则不会。

实际问题是违反了里氏替换原则:在需要 y 的子类中,如果未提供 y 我必须抛出异常,而在 A.f(未实现)我没有抛出任何异常。

A 的设计也很糟糕,因为我提供了一个方法 f,一些子类确实需要它,其中一些需要稍微不同的版本。显然,我应该将接口(interface)设计得尽可能小(接口(interface)隔离)。

这实际上是一个一般性问题,不仅与 Dart 相关。

那么,如何处理可选参数才不违反里氏代换原则呢?尤其是,您将如何处理我的情况,以免我也违反接口(interface)隔离原则?

我现在看到的唯一合理的解决方案(针对我的特定问题)是创建扩展 A 并且实际上需要 f< 中的 y 的当前子类 实际扩展(或实现,如果 A 实际上是一个接口(interface))另一个具有方法 f(x, y) 的基类,这是两个参数所在的位置必需的。但是如何处理可选参数的问题仍然存在!

最佳答案

正如我所读,问题是您想要实际上不能替代父类(super class)的子类。你想要两个类(class),AB , 两者都实现相同的 API,即使这些类并不是真正可以互换的。其中一个只使用一个参数(并且可以说,应该只接受一个参数),另一个需要两个参数。这两个类只是不兼容,因此添加一个通用父类(super class)以某种方式抽象出不兼容的操作注定要失败。

也就是说,如果您已经知道 A 的某些子类不会使用 foo 的第二个参数, 那么为什么它们是 A 的子类?因为作为 A 的子类他们应该接受任何论点 A接受并以与 A.foo 的契约(Contract)一致的方式使用它文档。

问题不在于可选参数,而是父类(super class)中的可选参数。如果一个参数在父类(super class)中是可选的,那么它在所有子类中也必然是可选的,因为子类需要以与父类(super class)相同的方式调用。s。一个接受 (x, [y]) 的函数不能用只接受一个或两个参数的参数代替,反之亦然。子类必须比父类(super class)允许更多,而不是更少,并且从可选参数到非可选参数允许较少

如果你有课

class X { foo(x) {} }
class Y { foo(x, y) {} }
class Z implements X, Y { foo(x, [y]) {} }

然后它起作用了,因为 Z允许超过 XY .使用 Z因为父类(super class)而不是子类是行不通的,这与健全和安全的方向背道而驰。

关于oop - 当方法有可选参数时,如何不违反 Liskov 替换原则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45936940/

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