LSP定义指出,如果S是T的子类型,则程序中类型T的对象可以用类型S的对象替换,而无需更改该程序的任何所需属性。
例如,我有以下课程 这是否违反(前提条件不能在子类型中得到加强)。 我正在努力解决这个问题,有人可以提供一个很好的例子来理解它。
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
答案 0 :(得分:0)
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
在我看来,这是更复杂的,因为很难明确指出。我能想到的唯一示例是保持属性为非Null,假设在示例中您拥有不使用IP的Switch(也许使用MAC-addr),如果Switch接口期望ip
字段应该不为None,您的MAC-Switch将会中断该接口。
希望对您有帮助!