为了账号安全,请及时绑定邮箱和手机立即绑定

需要清楚理解 liskov 替换原则

需要清楚理解 liskov 替换原则

德玛西亚99 2021-12-26 14:44:14
LSP 定义指出,如果 S 是 T 的子类型,那么程序中的类型 T 的对象可以用类型 S 的对象替换,而不会改变该程序的任何所需属性。不能在子类型中加强先决条件不能在子类型中削弱后置条件。超类型的不变量必须保留在子类型中。例如,我有下面的类,这是否违反了(不能在子类型中加强前提条件)。我正在努力解决这个问题,有人可以提供一个很好的例子来理解它。Class Switch:   def __init__(self,ip,dc):       self.ip=ip       self.dc=dcclass CiscoSwitch(Switch):   def __init__(self,ip,dc,zone):       super().__init__(ip,dc)       self.zone=zoneclass JuniperSwitch(Switch):   def __init__(self,ip,dc,zone):       super().__init__(ip,dc)       self.zone=zone
查看完整描述

1 回答

?
呼啦一阵风

TA贡献1802条经验 获得超6个赞

LSP 原理是通过接口起作用的,即对象/值中什么是公共的。在 Python 的情况下,您拥有公共的属性和方法,因此,如果您正在实现一个接口,您必须遵守它。在您的示例中,Switch该类仅针对其属性定义了一个接口,即它具有ipdc字段。既然你在呼唤superCiscoSwitchJuniperSwitch,它们都具有这些领域,因此实施的“接口” Switch,他们可能会取代它。

现在,让我们解决您提到的条件:

  1. 不能在子类型中加强先决条件

假设您有一个接口,其中包含一个为形状着色的方法,并且该方法仅接受十六进制颜色 ( "#123456") 或 rgb 颜色 ( (123,124,125))。假设您创建了一个实现此接口的 Rectangle 类,但它仅接受 rgb 颜色。你在强化前提条件。如果您的代码中有这一行: generic_shape.color("#123456")

您无法替换其中的 Rectangle,因此您正在破坏 LSP。

  1. 不能削弱子类型中的后置条件

一个经典的例子是返回None一个不应该返回的方法None。假设在Shape接口中,你有一个getSide方法,你创建了一个Circle类,在实现这个方法的时候,你返回了None。这打破了调用者的预期并可能导致意外错误:

side = generic_shape.get_side() # suppose it is a circle
scaled_side = side * 2 # you get an error
  1. 超类型的不变量必须保留在子类型中

这个在我看来比较复杂,因为很难说清楚。我能想到的唯一例子是保持一个非空的属性,假设在你的例子中你有一个不使用 IP(可能使用 MAC-addr)的交换机,如果 Switch 接口期望该ip字段不应该是 None,你的MAC-Switch 将破坏这个接口。

我希望它有帮助!


查看完整回答
反对 回复 2021-12-26
  • 1 回答
  • 0 关注
  • 185 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号