python 设计模式(二) 六大设计原则二 里氏替换原则(Liskov Substitution Principle)

里氏替换原则简称LSP。定义:所有引用基类的地方必须能够透明地使用其子类的对象。

所谓对象是一组状态和一系列行为的组合。状态是对象的内在特性,行为是对象的外在特性。LSP所表述的就是在同一个继承体系中的对象应该有共同的行为特征我们在设计对象时是按照行为进行分类的,只有行为一致的对象才能抽象出一个类来。因此,如果说鸵鸟和企鹅属于鸟类的话,就违背了里氏替换原则。

如何规范地遵从里氏替换原则:

1 子类必须完全实现父类的抽象方法,但不能覆盖父类的非抽象方法

2 子类可以实现自己特有的方法

3 当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。

4 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

5 子类的实例可以替代任何父类的实例,但反之不成立

举例如下

import abc

class Abstract_bird(object):

    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def fly(self):
        pass

    @abc.abstractmethod
    def tweet(self):
        pass

    def eat(self):
        print('bird is eating')


class Eagle(Abstract_bird):

    def fly(self):
        print('eagle is flying')

    def tweet(self):
        print('eagle is tweeting')

    def drink(self):
        print('eagle is drinking')


if __name__ == '__main__':
    bird = Abstract_bird()
    bird.fly()
    bird.tweet()
    bird.eat()
    print('把所有父类Abstract_bird替换为子类Eagle如下')
    eagle = Eagle()
    eagle.fly()
    eagle.tweet()
    eagle.eat()

结果如下

bird is eating
把所有父类Abstract_bird替换为子类Eagle如下
eagle is flying
eagle is tweeting
bird is eating

以上代码中,实现了父类Abstract_bird和子类Eagle,Abstract_bird类实现了三个方法,方法fly和tweet是抽象方法,方法eat是一般方法。子类Eagle中实现了自己特有的方法drink。以上代码遵从了里氏替换原则:1 子类必须完全实现父类的抽象方法,但不能覆盖父类的非抽象方法。2 子类可以实现自己特有的方法。因此,结果也符合预期。但如果让父类的实例去替换子类的实例的话一定会出错的,因为父类中没有子类特有的方法drink




你可能感兴趣的:(python,python,设计模式)