<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] >[success] # 多態 ~~~ 1.多態的英文'prolymorphism',也就是'poly(復數)' + 'morph(形態)',字面意思復數形態 2.多態:'同一操作作用于不同的對象,可以有不同的解釋,產生不同的執行結果',書 里白話文解釋是給不同的對象發送同一個消息的時候,這些對象會根據這個消息分別, 給出不同的反饋 2.1 書中給了一個故事的比喻:'家里有一只鴨和一只雞',當主人發出指令'叫'的時候, 鴨子會'嘎嘎嘎',雞會'咯咯咯',他們同樣是'動物,都可以叫',根據指令發出不同的叫聲 2.2 利用代碼的思想去分析這個比喻'動物是一個類,這個類有叫的方法','雞和鴨是繼承了動物類' ,你家里的'雞和鴨是你生成的實例活生生的',你的命令'叫'就好比鴨子類型選會'嘎嘎叫加入合唱團' 這也解釋了第一條中,不同對象'鴨和雞'都讓他們叫,但是產生的結果過'咯咯咯'和'嘎嘎嘎' 3.像在靜態類型語言中,接口的多種不同的實現方式即為多態,或者重寫重載也算 多態一種表現形式,js雖然沒有接口的概念但是它有繼承的概念,繼承后的重寫可以 理解成多態,還要注意由于動態類型語言js為例他們有類型,所以它在調用的時候又不關心 你的類型,只要有這個方法即可,這也是動態類型語言在多態和鴨子類型的便捷之處 4.多態在使用的時候可以總結成:'做什么' 和 '誰去做以及怎樣去做'分離開,簡單的說就是 '不變的事物'和'可能改變的事物分離開' ~~~ >[info] ## 多態詳解 >[danger] ##### js 的一段'多態',引出'開放封閉原則' ~~~ 1.下面的代碼用多態的概念去分析,同一操作了兩個不同對象'雞和鴨',他們的叫聲 產生了'不同的執行結果'一個'嘎嘎'一個'咯咯' 2.下面的代碼符合需求但是如果你家里的寵物多了一只狗,你需要去改寫'makeSound' 隨著家里的成員越來越多(我們的代碼需要越來越多),整個'makeSound'方法會越來越 大,修改的地方越多,程序產生錯誤問題的可能性就越大 3.下面的案例卻不符合我們第四條說的分離思想,動物叫是'不變的事物',但是動物叫聲 根據不同動物的種類是'可變的',如果將叫這個行為'分割出來',把他們叫后的行為結果 '可變的部分封裝起來',這樣只需要增加代碼就可以了,不需要改變代碼 4.剛才說的思想其實是開放封閉原則,其核心的思想是: '軟件實體應該是可擴展,而不可修改的。也就是說,對擴展是開放的,而對修改是封閉的。' 因此,開放封閉原則主要體現在兩個方面: '對擴展開放,意味著有新的需求或變化時,可以對現有代碼進行擴展,以適應新的情況。' '對修改封閉,意味著類一旦設計完成,就可以獨立完成其工作,而不要對類進行任何修改。' ~~~ ~~~ function makeSound(animal) { if(animal instanceof Duck){ console.log('嘎嘎嘎') }else if(animal instanceof Chicken){ console.log('咯咯咯') } } // es5 聲明類 鴨子類 function Duck(){} // es5 聲明類 雞類 function Chicken() {} const duck = new Duck() // 你家那只活著的鴨子對象 const chicken = new Chicken() // 你家那只活著的雞對象 //發出指令叫 makeSound(duck) makeSound(chicken) ~~~ >[danger] ##### 將上面的案例改寫成真正的多態 ~~~ 1.下面案例的好處,我們將'不可變'和'可變分離',就不會因為家庭里添加了新的 寵物需要修改'makeSound'方法,添加的新成員它們接受到指令的時候自動就會 觸發他們'sound'方法 ~~~ ~~~ // 不變的地方就是叫聲 function makeSound(animal) { animal.sound() } // ----- 下面案例中 講可變叫聲內具體實踐封裝起來----- // es5 聲明類 鴨子類 function Duck(){} Duck.prototype.sound = function () { console.log('嘎嘎嘎') } // es5 聲明類 雞類 function Chicken() {} Chicken.prototype.sound = function () { console.log('咯咯咯') } const duck = new Duck() // 你家那只活著的鴨子對象 const chicken = new Chicken() // 你家那只活著的雞對象 //發出指令叫 makeSound(duck) makeSound(chicken) ~~~ >[info] ## 靜態類型的多態 -- 類型檢查 ~~~ 1.因為js 是動態類型,沒有類型檢查的說,所以我們不需要關心參數類型 只要參數有這個方法即可,但是隨著'TS'的應用前端也需要考慮類型問題 2.下面的案例是以java為例 ~~~ ~~~ public class Duck { // 鴨子類 public void makeSound(){ System.out.println( "嘎嘎嘎" ); } } public class Chicken { // 雞類 public void makeSound(){ System.out.println( "咯咯咯" ); } } public class AnimalSound { public void makeSound( Duck duck ){ // (1) duck.makeSound(); } } public class Test { public static void main( String args[] ){ AnimalSound animalSound = new AnimalSound(); Duck duck = new Duck(); animalSound.makeSound( duck ); // 輸出:嘎嘎嘎 } } ~~~ * 如果傳入的雞實例 ~~~ public class Test { public static void main( String args[] ){ AnimalSound animalSound = new AnimalSound(); Chicken chicken = new Chicken(); animalSound.makeSound( chicken ); // 報錯,只能接受Duck類型的參數 } } ~~~ ~~~ 1.根據上面的java 案例要說一個問題,由于類型檢查'AnimalSound '類中的'makeSound' 只接受'Duck'類型的導致當我們用'Chicken'的實例當成參數的時候報錯 2.但是java有一個特點就是可以向上轉型,用書中的解釋,當我們看到天上的喜鵲和麻雀 我們會說'一只喜鵲在飛','一只麻雀在飛'。但我們也可以說成'一只鳥在飛',我們把'喜鵲' 和'麻雀'向上轉型叫做了'鳥',如果我們的'雞'和'鴨'都繼承了動物類,當我們調用'AnimalSound ' 類中的'makeSound'方法時候,讓檢查的類型是'動物'即實現'向上轉型' public class AnimalSound { public void makeSound( Animal animal ){ // (1) animal.makeSound(); } } 3.這里有個小故事,工作時候我們最近在使用'ts'其中有一段和這個特別類似的代碼實現效果, 我看當時規定的傳參類型是他們的父類,我變產生了不解,不應該是枚舉類型指定能使用的 類么,現在明白了可以利用'向上轉型'的改變只檢查他們的父類即可形成'繼承多態效果' 4.因此可以得到一個結論:js 和java 不同點,js是動態類型語言,它在使用的時候即可表現 成'鴨子'又可以表現成'雞',他的多態是與生俱來的,不需要像java進行一些其他途徑來實現 多態,這也是'pyhon' 為什么提出了'鴨子類型',我么也可以從這些天生就可以鴨子類型的語言 體會到的'好處' ~~~ >[info] ##### 在面向對象中設計時候 -- 多態的作用 ~~~ 1.用書中的話來說,'將過程化的條件分支語句轉換為對象的多態性,從而消除這些條件語句' ,像上面的案例我們從if判斷是那個類,在決定發出什么聲音,到后來真正的多態,我們不關心 你是誰怎么叫,只要你能叫,發出指令你執行就可以 2.書中還舉了個<<重構:改善既有代碼的設計>>我在這里簡單概括這個例子:拍電影的時候, 導演喊開始,演員道具,燈光攝影都要去做自己的事,如果每一次導演喊開始,然后還有一個 個再去指導他們做的事,就會形成大量的if語句,這時候如果這些人都是類,他們將自己行為 封裝好,那導演喊開始,是不是就很像多態 ~~~ >[info] ## 書中的地圖API 的例子 ~~~ 1.書中給的場景:需要編寫地圖應用一開始選擇谷歌地圖,后來因為需求部分需要百度地圖, 就可以利用多態的形式 ~~~ ~~~ const googleMap = { show: function () { console.log('開始渲染谷歌地圖'); } }; const baiduMap = { show: function () { console.log('開始渲染百度地圖'); } }; const renderMap = function (map) { if (map.show instanceof Function) { map.show(); } }; renderMap(googleMap); // 輸出:開始渲染谷歌地圖 renderMap(baiduMap); // 輸出:開始渲染百度地圖 // 錯誤使用多態(過多的if判斷) const renderMap = function (type) { if (type=== 'google') { googleMap.show() }else if(type === 'baidu'){ baidu.show() } } ~~~
                  <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>

                              哎呀哎呀视频在线观看