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




發佈了54 篇原創文章 · 獲贊 11 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章