Inheritance 例外的Liskov替换原理

Inheritance 例外的Liskov替换原理,inheritance,polymorphism,liskov-substitution-principle,Inheritance,Polymorphism,Liskov Substitution Principle,我正在读《敏捷原则、模式和实践》一书中关于LSP的内容。 它指出: “常规的[衍生工具]再声明可能 仅用一个相等或较弱的条件替换原始先决条件,用一个相等或较强的条件替换原始后决条件。” “较弱”一词可能令人困惑。如果X不强制执行Y的所有约束,则X比Y弱。如何执行并不重要 X实施了许多新的约束 我们如何在例外情况下理解它 LSP适用于类型。因此,大多数OOP语言中的类。有三种方法来考虑你的问题: 1。被视为类型的异常 异常类型,例如C++中的,可以导出到更专门的异常中。为了便于错误处理,应使用LS

我正在读《敏捷原则、模式和实践》一书中关于LSP的内容。 它指出:

“常规的[衍生工具]再声明可能 仅用一个相等或较弱的条件替换原始先决条件,用一个相等或较强的条件替换原始后决条件。”

“较弱”一词可能令人困惑。如果X不强制执行Y的所有约束,则X比Y弱。如何执行并不重要 X实施了许多新的约束


我们如何在例外情况下理解它

LSP适用于类型。因此,大多数OOP语言中的类。有三种方法来考虑你的问题:

1。被视为类型的异常

异常类型,例如C++中的,可以导出到更专门的异常中。为了便于错误处理,应使用LSP代码

异常的行为通常很差,只是传输一些关于错误条件的附加信息,所以一般来说这并不太困难

2。视为失败先决条件的异常

例外情况应与正常情况下不可能出现的例外情况相对应。因此,引发异常意味着不存在预期的正常条件

因此,在派生类型中引发异常的条件应等于或弱于常规类型中的条件

让我们来举一个极端的例子。假设给定例程的基类中没有预见到异常。您可能期望甚至指定一个
nothrow
。使用它的代码,这个例程会考虑它是安全的,并且不会预见到任何异常捕获。假设您随后将该类派生为引发异常的类(即,先决条件更强、限制更严格):如果引发异常,则为基类编写的代码将措手不及,并且基类的常规代码可能会被专用类破坏。所以LSP会被破坏

3。被视为特殊结果/后条件的例外情况

您可能会争辩说,在某些情况下,例外情况是一种特殊的post条件。返回值的替代值

我对这种解释感到相当不舒服(因为这不是许多语言设计师的理解,请参阅关于nothrow的讨论)。但我没有进一步的客观论据来证明它无效

因为LSP是关于合同的,所以您可以做出这个设计决策。在这种情况下,一个更专业化的类可以抛出一个更专业化的异常(因此推理将基于异常类型)。但是派生类是否真的应该抛出至少与原始类一样多的异常呢?那听起来有点反直觉。转到2