若我将public方法添加到子类中,并且客户端程序调用added方法,则客户端程序不能使用父对象而不是子类。
import unittest
class BaseClass(object):
def doSomething(self):
pass
class SubClass(BaseClass):
def doStuff(self):
pass
class Client(object):
def __init__(self, obj):
self.obj = obj
def do(self):
self.obj.doStuff()
class LSPTestCase(unittest.TestCase):
def test_call_subclass_method(self):
client = Client(SubClass())
client.do()
def test_call_baseclass_method(self):
client = Client(BaseClass())
with self.assertRaises(AttributeError):
client.do()
if __name__ == '__main__':
unittest.main()
这个案子违反了LSP?
向子类添加方法不会违反LSP。但是,如果您通过从父类向下转换来调用该方法,则会违反该规则。
罗伯特C.Martin在他的LSP/SOLID论文的开头指出:
根据对象的类型选择函数
(...) 这是一个简单违反Liskov替换原则的例子。
通常,如果您最终需要向下转换或使用instanceof操作符,那么最好重新使用继承,以支持其他方法,如组合。
否,只要从父类继承的所有方法都遵循与父类相同的契约,那么LSP就会保留。
LSP的全部要点是能够将子类作为父类传递,而没有任何问题。它没有提到不能向下投射额外的功能。
问题内容: 我的情况与Code Complete中Steve McConnell 提到的情况非常相似。我唯一的问题是基于车辆,而三轮车恰好是根据法律,属于汽车。到目前为止,汽车只有四个轮子。无论如何,我的域都不必要地复杂,因此很容易遵循下面的cats示例。 对重写例程并且在派生例程中不执行任何操作的类要保持怀疑。这通常表明基类的设计存在错误。例如,假设您有一个Cat类和一个例程Scratch(),
我是OOP的新手。最近我读到了关于Liskov替换原理的文章。 在下面给出的代码中,Square类继承Give_区域。假设Square类与Square相关(比如有效性检查)。Give_Area给出正方形的面积(4个顶点位于圆的周长上)和圆的面积。所以,如果给我一个半径,我必须打印圆和正方形的面积(由放置在圆周长上的顶点组成)。为了得到圆的面积,我使用了一个参数。但在求平方面积时没有参数。因此,我在
问题内容: Liskov替换原理是SOLID的原理之一。我已经读过几次这个原理,并试图理解它。 这就是我的所作所为, 此原则与类层次结构之间的强行为契约有关。子类型应该能够被超类型替换而不会违反合同。 我也读过其他文章,对这个问题我有些失落。难道方法不违反LSP? 上面链接的文章摘录: 换句话说,当通过对象的基类接口使用对象时,用户仅知道基类的前提条件和后置条件。因此, 派生对象不能期望此类用户遵
我正在阅读为什么Java中的数组协方差不好(为什么数组是协方差的,而泛型是不变的?)。如果是的子类型,则是的子类型。这是一个问题,因为这样的事情是可以做的: 这与“正确”实现的泛型不同。不是的子类型 我试图理解为什么它是坏的本质,并且刚刚读了关于LSP的文章。它有没有违反LSP?似乎没有明显的违规行为。
有人能告诉我下面的例子是否违反了LSP吗? 我有一个例子: 和子类: 和主类: 在此示例中,子类添加名为 的新属性,并通过对其自己的属性 进行附加检查来覆盖方法。 在main方法中,我创建了2个对象。第一个是类型的对象,第二个是类型的对象。 当验证人员时,因为所有前提条件都是正确的,所以它是正确的,但是对于员工,它将抛出< code > IllegalArgumentException ,因为它与
来自维基百科, Liskov的行为子类型概念定义了对象的可替代性概念;也就是说,如果S是T的子类型,则程序中T类型的对象可以替换为S类型的对象,而不改变该程序的任何期望属性(例如正确性)。 假设以下类层次结构: 基本抽象类-。它有一个只读属性,在后继程序中被重写。 基类的继承者-,它重写并返回灰色。 Cat的继任者-,它覆盖并返回带条纹的。 然后我们声明一个方法,参数类型为(不是)。 向该方法发送