<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 里氏替換原則 英文名稱(Liskov Substitution Principle,LSP): 定義:**所有引用基類的地方必須能夠透明地使用其子類的對象** 我的理解: **父類出現的地方也可以用子類來替換,而子類出現的地方父類不一定能替換。** 里氏替換原則的為繼承定義的規范,包括4層含義 **1、子類必須完全實現父類的方法** **2、子類可以有自己的個性** **3、覆蓋或實現父類的方法時輸入參數可以被放大** **4、覆寫或實現父類的方法時輸出結果可以被縮小** 模擬CS游戲 戰士可以拿槍去殺敵人,setGun()給戰士設置不同的槍。killEnemy()射殺敵人。 抽象類,AbstractGun,void shoot()方法 槍類MachineGun(機槍),Rifle(步槍),Handgun(手槍)實現抽象類方法 -----這個類的設計原理是,每種槍都有一個“射擊”的方法,因此抽象出來使用。 ![](https://box.kancloud.cn/2016-06-06_57553406749c5.jpg) ~~~ public class Test { public static void main(String[] args) { Soldier s = new Soldier(); s.setGun(new Handgun()); s.killEnemy(); } } abstract class AbstractGun{ public void shoot(){}; } /** * 戰士類具有殺死敵人的方法,設置不同類別的槍的方法 * @author admin * */ class Soldier{ private AbstractGun gun; public void setGun(AbstractGun gun){ this.gun = gun; } public void killEnemy(){ gun.shoot(); System.out.println("正在射殺敵人..."); } } class MachineGun extends AbstractGun{ @Override public void shoot() { System.out.println("機關槍掃射..."); } } class Rifle extends AbstractGun{ @Override public void shoot() { System.out.println("步槍射擊..."); } } class Handgun extends AbstractGun{ @Override public void shoot() { System.out.println("手槍射擊..."); } } ~~~ ## 子類必須完全實現父類的方法 當如果又來了一個玩具槍時,我們一貫的思想是,將玩具槍繼承AbstractGun類,實現shoot方法。 但是依照情景玩具槍不具備射擊的能力。因此玩具槍不能直接繼承AbstractGun類。因為它不能完整的實現父類的方法。 ![](https://box.kancloud.cn/2016-06-06_575534068bd2f.jpg) ## 子類可以有自己的個性 這句話很好理解,子類繼承父類,不僅擁有父類的方法和屬性,而且自己還可以用于其他的方法和屬性,并且可以覆寫父類的方法,重載父類的方法等。![](https://box.kancloud.cn/2016-06-06_57553406a89e2.jpg) ~~~ <span style="font-size:18px;">public class Test { public static void main(String[] args) { /* Soldier s = new Soldier(); s.setGun(new Handgun()); s.killEnemy(); System.out.println("----------------");*/ Snipper juji = new Snipper(); juji.setGun(new AUG()); juji.killEnemy(); } } abstract class AbstractGun{ public void shoot(){}; } class Snipper{ private AUG aug; public void setGun(AUG gun){ this.aug = gun; } public void killEnemy(){ aug.zoomOut(); aug.shoot(); System.out.println("狙擊手正在射殺敵人..."); } } class AUG extends Rifle{ @Override public void shoot() { System.out.println("狙擊槍射擊..."); } public void zoomOut(){ System.out.println("狙擊槍正在瞄準"); } }</span> ~~~ **覆蓋或實現父類的方法時輸入參數可以被放大** ---這句話類似于子類重載父類的方法時,保證子類的傳入參數的范圍大于父類的參數。 如果沒有滿足以上條件的話,就不滿足父類存在的地方子類也存在的條件,因而違背了里氏替換原則。 例如兩個代碼的比較: ~~~ package hpu.lzl.lsp; import java.util.Collection; import java.util.HashMap; import java.util.Map; public class Test02 { public static void main(String[] args) { Father f = new Father(); HashMap<String, String> hashMap = new HashMap<String, String>(); f.doSomething(hashMap); System.out.println("里氏替換----------------父類存在的地方子類應該也可以存在-----------"); Son s = new Son(); s.doSomething(hashMap); } } /** * 定義一個父類,實現將map集合轉換成Collection集合 * @author admin * */ class Father{ public Collection doSomething(HashMap<String,String> map){ System.out.println("父類方法被執行..."); return map.values(); } } /** * 子類重載父類的方法 * @author admin * */ class Son extends Father{ /** * 注意此處是重載,返回值類型,方法名相同,傳入參數不同。 * 保證傳入的參數類型的范圍大于父類。 */ public Collection doSomething(Map<String, String> map) { System.out.println("子類方法被執行..."); return map.values(); } } ~~~ 輸出結果: ~~~ 父類方法被執行... 里氏替換----------------父類存在的地方子類應該也可以存在----------- 父類方法被執行... ~~~ 方法二: ~~~ package hpu.lzl.lsp; import java.util.Collection; import java.util.HashMap; import java.util.Map; public class Test02 { public static void main(String[] args) { Father f = new Father(); HashMap<String, String> hashMap = new HashMap<String, String>(); f.doSomething(hashMap); System.out.println("里氏替換----------------父類存在的地方子類應該也可以存在-----------"); Son s = new Son(); s.doSomething(hashMap); } } /** * 定義一個父類,實現將map集合轉換成Collection集合 * @author admin * */ class Father{ public Collection doSomething(Map<String,String> map){ System.out.println(".......父類方法被執行..."); return map.values(); } } /** * 子類重載父類的方法 * @author admin * */ class Son extends Father{ /** * 注意此處是重載,返回值類型,方法名相同,傳入參數不同。 */ public Collection doSomething(HashMap<String, String> map) { System.out.println("子類方法被執行..."); return map.values(); } } ~~~ 輸出結果: ~~~ .......父類方法被執行... 里氏替換----------------父類存在的地方子類應該也可以存在----------- 子類方法被執行... ~~~ ## 覆寫或實現父類的方法時輸出結果可以被縮小 分兩類解釋:一,子類覆寫父類的方法時,要求子類與父類的方法名相同,輸入的參數相同,返回值值范圍小于或等于父類的方法。二,子類重載父類的方法時,要求方法的輸入參數類型或數量不同,在里氏替換原則要求下,子類的輸入參數要大于或等于子類的輸入參數。 我的理解:里氏替換原則,就是在繼承的概念上有定義了一些開發時需要的規范。例如子類繼承父類時,需要擁有父類的方法(這個意思是,在給對象分類時,一定要抽取相同的屬性的方法。例如玩具槍雖然屬性與其他槍相同,但是不能殺死敵人,因而不能繼承AbstractGun類。)。嚴格按照這個規范來進行開發,為后期版本升級,增添子類時都可以很好的維護。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看