向子类添加公共方法是否违反了LSP(里氏替换原则)?

5
如果我在子类中添加公共方法,并且客户端程序调用了添加的方法,客户端程序不能使用父对象代替子类。
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原则吗?

3
LSP原则表明,子类可以替代父类使用,但父类不能替代子类使用。 - David Conrad
这是什么语言? - weston
@weston 这个语言是Python - pjxiao
2个回答

5
只要从父类继承的所有方法都遵循与父类相同的约定,则 LSP 就得以保留。LSP 的整个要点在于能够毫无问题地传递子类作为父类。它并不意味着不能向下转换以获得额外的功能。

2
将文本翻译成中文:

在子类中添加方法不违反LSP。然而,如果您通过从父类向下转换来调用该方法,则会违反LSP。

Robert C. Martin 在他的 LSP / SOLID paper 开头就指出:

根据对象的类型选择一个函数

这是违反里氏替换原则的一个简单例子。

通常,如果您陷入需要使用向下转型或使用instanceof运算符的情况中,最好重新考虑使用继承,而采用其他方法如组合等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接