需要清楚了解liskov替代原理

时间:2019-04-02 15:04:24

标签: python oop solid-principles liskov-substitution-principle

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

1 个答案:

答案 0 :(得分:0)

LSP原理通过接口起作用,即在对象/值中是公共的。对于Python,您具有公共的属性和方法,因此,如果要实现接口,则必须遵循该属性。 在您的示例中,Switch类仅根据其属性定义接口,即,它具有ipdc字段。由于您要在superCiscoSwitch中调用JuniperSwitch,因此它们都具有这些字段,因此实现了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. 超类型的不变量必须保留在子类型中

在我看来,这是更复杂的,因为很难明确指出。我能想到的唯一示例是保持属性为非Null,假设在示例中您拥有不使用IP的Switch(也许使用MAC-addr),如果Switch接口期望ip字段应该不为None,您的MAC-Switch将会中断该接口。

希望对您有帮助!