- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在程序中遇到了一个设计问题,原因是 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),A
和 B
, 两者都实现相同的 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
允许超过 X
或 Y
.使用 Z
因为父类(super class)而不是子类是行不通的,这与健全和安全的方向背道而驰。
关于oop - 当方法有可选参数时,如何不违反 Liskov 替换原则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45936940/
我正在尝试用 Swift 编写这段 JavaScript 代码:k_combinations 到目前为止,我在 Swift 中有这个: import Foundation import Cocoa e
我是一名优秀的程序员,十分优秀!