猿问

需要清楚理解 liskov 替换原则

LSP 定义指出,如果 S 是 T 的子类型,那么程序中的类型 T 的对象可以用类型 S 的对象替换,而不会改变该程序的任何所需属性。

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

  2. 不能在子类型中削弱后置条件。

  3. 超类型的不变量必须保留在子类型中。

例如,我有下面的类,这是否违反了(不能在子类型中加强前提条件)。我正在努力解决这个问题,有人可以提供一个很好的例子来理解它。

Class Switch:

   def __init__(self,ip,dc):

       self.ip=ip

       self.dc=dc


class CiscoSwitch(Switch):

   def __init__(self,ip,dc,zone):

       super().__init__(ip,dc)

       self.zone=zone


class JuniperSwitch(Switch):

   def __init__(self,ip,dc,zone):

       super().__init__(ip,dc)

       self.zone=zone


德玛西亚99
浏览 186回答 1
1回答

呼啦一阵风

LSP 原理是通过接口起作用的,即对象/值中什么是公共的。在 Python 的情况下,您拥有公共的属性和方法,因此,如果您正在实现一个接口,您必须遵守它。在您的示例中,Switch该类仅针对其属性定义了一个接口,即它具有ip和dc字段。既然你在呼唤super中CiscoSwitch和JuniperSwitch,它们都具有这些领域,因此实施的“接口” Switch,他们可能会取代它。现在,让我们解决您提到的条件:不能在子类型中加强先决条件假设您有一个接口,其中包含一个为形状着色的方法,并且该方法仅接受十六进制颜色 ( "#123456") 或 rgb 颜色 ( (123,124,125))。假设您创建了一个实现此接口的 Rectangle 类,但它仅接受 rgb 颜色。你在强化前提条件。如果您的代码中有这一行: generic_shape.color("#123456")您无法替换其中的 Rectangle,因此您正在破坏 LSP。不能削弱子类型中的后置条件一个经典的例子是返回None一个不应该返回的方法None。假设在Shape接口中,你有一个getSide方法,你创建了一个Circle类,在实现这个方法的时候,你返回了None。这打破了调用者的预期并可能导致意外错误:side = generic_shape.get_side() # suppose it is a circle scaled_side = side * 2 # you get an error超类型的不变量必须保留在子类型中这个在我看来比较复杂,因为很难说清楚。我能想到的唯一例子是保持一个非空的属性,假设在你的例子中你有一个不使用 IP(可能使用 MAC-addr)的交换机,如果 Switch 接口期望该ip字段不应该是 None,你的MAC-Switch 将破坏这个接口。我希望它有帮助!
随时随地看视频慕课网APP

相关分类

Python
我要回答