gpt4 book ai didi

python - 重载(不是覆盖)是否打破了 Liskov 替换原则?

转载 作者:行者123 更新时间:2023-12-04 09:54:27 25 4
gpt4 key购买 nike

有大量关于 LSP 的讨论,但所有这些讨论似乎都过于模糊。
AFAIK,LSP 声明正确 覆盖 (不重载)子类中的父类(super class)方法,应确保子方法:

  • 不会产生父方法在任何情况下都不会引发的新型异常
  • 具有与父方法相同的签名(在强类型语言的情况下)
  • 具有与签名
  • 相同的语义含义
  • 返回相同类型的值
  • 返回相同语义的值

  • 来自 semantic meaning我的意思是,如果基类方法暗示它返回 int而这个 int意味着,比如说,美元或欧元,那么重载的方法也应该暗示返回的值是美元或欧元,即使在一种情况下返回 'RUB' 也会违反 LSP。

    但是如果我的基类看起来像这样(示例是在 Python 中):
    class A:

    func(x: int) -> int
    return x*2

    class B(A):

    func(x: int, y: string) -> int
    return x*y

    所以我的问题中有两个子问题:
  • contract这个词是什么意思更实际的意思是什么?是否与interface同义? ?
  • 使用基类中不存在的签名(在参数列表的一部分中)重载是否违反 LSP?
  • 最佳答案

    答案取决于语言。

    在典型的强类型 OO 语言(如 Java、C++、C# 等)中,当您编写像 a.func(b,c) 这样的方法调用时,实际调用的方法是根据方法名、接收类型(本例中为a的类型)、参数的数量和类型来确定的。

    在这样的语言中,具有不同数量参数或不同类型参数的方法是完全不同的方法。拥有不同数量的参数就像拥有不同的名称一样。当您“重载”一个方法时,就像使用不同的名称创建一个方法一样,因此您不会通过重载基类中的方法而违反 LSP。

    不过,您的问题似乎是关于 python 的,并且在典型的动态类型语言(如 python、JavaScript 等)中,当您编写像 a.func(b,c) 这样的方法调用时,要调用的方法仅按名称查找(在与接收对象关联的表中查找)。在这样的语言中,没有方法或函数的重载之类的东西。

    在您的示例中,您覆盖了 func 的单参数定义。带有两个参数的函数。这意味着派生类的使用者不能再调用 func使用一个参数,这确实违反了 LSP。

    关于python - 重载(不是覆盖)是否打破了 Liskov 替换原则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61950209/

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