設計模式六大原則:里氏替換原則


目錄: 

  設計模式六大原則:單一職責原則

  設計模式六大原則:接口隔離原則 

  設計模式六大原則:依賴倒置原則

  設計模式六大原則:里氏替換原則

  設計模式六大原則:迪米特法則

  設計模式六大原則:開閉原則

里氏替換原則:

  子類應當可以替換父類並出現在父類能夠出現的地方。比如:公司搞年度派對,都有員工都可以抽獎,那么不管是新員工還是老員工,也不管是總部員工還是外派員工,都應當可以參加抽獎。

  里氏替換至少包含一下兩個含義:

    1、里氏替換原則是針對繼承而言的,如果繼承是為了實現代碼重用,也就是為了共享方法,那么共享的父類方法就應該保持不變,不能被子類重新定義。子類只能通過新添加方法來擴展功能,父類和子類都可以實例化,而子類繼承的方法和父類是一樣的,父類調用方法的地方,子類也可以調用同一個繼承得來的,邏輯和父類一致的方法,這時用子類對象將父類對象替換掉時,當然邏輯一致,相安無事。

    2、如果繼承的目的是為了多態,而多態的前提就是子類覆蓋並重新定義父類的方法,為了符合LSP,我們應該將父類定義為抽象類,並定義抽象方法,讓子類重新定義這些方法,當父類是抽象類時,父類就是不能實例化,所以也不存在可實例化的父類對象在程序里。也就不存在子類替換父類實例(根本不存在父類實例了)時邏輯不一致的可能。 

案例:

 1 internal class Program
 2 {
 3     private static void Main(string[] args)
 4     {
 5         A a = new A();
 6         Console.WriteLine($"100-50={(a.func1(100, 50))}");
 7 
 8         B b = new B();
 9         Console.WriteLine($"100-50={(b.func1(100, 50))}");
10         Console.WriteLine($"100-50={(b.func2(100, 50))}");
11 
12         Console.ReadKey();
13     }
14 }
15 
16 internal class A
17 {
18     public int func1(int num1, int num2)
19     {
20         return num1 - num2;
21     }
22 }
23 
24 internal class B : A
25 {
26     //public int func1(int num1, int num2)
27     //{
28     //    return num1 + num2;
29     //}
30 
31     public int func2(int num1, int num2)
32     {
33         return func1(num1, num2) + 100;
34     }
35 }
view code

  由上述代碼可以看出,若類B在繼承類A時不注意,重寫了父類方法func1就會導致結果與預想的不一致,改變了父類原有的功能。故里氏轉換原則應滿足以下要求:

  1、子類可以實現父類的抽象方法,但不能覆蓋父類的非抽象方法

  2、子類可以增加自己特有的方法

  3、當子類的方法重載父類的方法時,方法的形參要比父類方法的輸入參數更寬松

  4、當子類的方法實現父類的抽象方法時,方法的返回值應比父類更嚴格

優點:

  可以大大減少程序的bug以及增強代碼的可讀性


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM