ES6——簡單的多態


簡單的多態
多態:
1.同一個接口,在不同情況下做不一樣的事情;相同的接口,不同的表現;
2.接口本身只是一組定義,實現都是子類里面;需要子類去實現的方法(子類只需重寫與父類同名的方法,即可達到覆蓋的效果),若子類有跟父類同名的方法,則會直接走子類的方法,不會走父類的;
3.非靜態方法中,仍然子類可通過super..方法名( )(舉例:super.say( ) ),來調用父類的方法(supe指向的事父類的原型)

重載:根據函數的參數類型,參數個數
作用:為一個函數提供了更豐富的行為


js的重載和其他語言的重載是完全不一樣的概念。因為js是一門弱類型語言, JS中函數可以傳入任意類型、任意個數的參數,通通可以通過在函數內使用this.arguments獲得。這樣,就無法實現同名函數參數列表不同實現不同功能。 而且js不是一個面向對象的語言, 即使在ES6中引入了Class類的概念, 但這只是一種語法糖, js並沒有實現真正的面向對象。 這里的重載其實可以簡單的理解就是為函數提供更豐富的行為
 
 
 
1. 父類的原型對象,是指父類的屬性prototype,二者不是一個東西,原型對象prototype上可以保存父類的一些方法(es6中,父類的屬性不放在原型對象上)。

2. 父類的原型對象的方法,是在constructor外面定義的,


2.“父類自身的方法”,則是直接在類身上定義的方法,
如果是指“父類原型上的方法”,則是在constructor外面定義的(第一張圖);如果是指“父類構造函數上的方法”,則是指在constructor里面定義的,
es6的構造函數constructor相當於es5的構造函數本身,它倆的作用都是給實例添加屬性,與es5的構造函數的原型對象prototype上的constructor不是一個東西。

 

 

super方法,用來繼承父類,所以super里的參數,是實例的屬性,在class外面,可以被實例直接訪問




 


//多態就是同一個接口,在不同情況下做不一樣的事情。即相同的接口,不同的表現
//接口本身只是一組定義,實現都是在類里面.可以直接理解成需要子類去實現的方法,子類只要重寫一個和父類同名的方法,就可以達到一個覆蓋的效果


//多態的優點,1、提高類的擴充性與靈活性
//2,暴露接口

  //重寫
            class Human{
                say(){
                    console.log('我是人')
                }
            }
            //子類如果擁有父類的同名方法,則會直接調用子類的方法,不會去走父 類的
            class Man extends Human{
                
                say(){
                    super.say()  //輸出 我是人
                    console.log('我是小哥哥')
                }
            }
            class Woman extends Human{
                //有的時候子類自己實現的內容,還是依賴父類中的一些操作,可以通過super.xxx的方式去進行訪問
                say(){
                    super.say();  //訪問父類的同名方法,這里super是作為對象的形式去訪問,在非靜態方法中訪問到的是父類的原型
                    
                    console.log('我是小姐姐')
                }
            }
            
            new Man().say();
            
            new Woman().say();

 

 

 

 

 

重載 是根據函數的參數類型以及參數個數去做不一樣的事情,

 

class SimpleCalc{
                addCalc(...args){
                    if(args.length === 0){
                        return this.zero();
                    }
                    if(args.length === 1){
                        return this.onlyOneArgument(args);
                    }
                    return this.add(args);
                }
                
                zero(){
                    return 0;
                }
                onlyOneArgument(){
                    return args[0];
                }
                add(args){
                    return args.reduce((a,b) => a+b , 0)  //返回a+b,從0開始作為基數傳遞
                }
            }
            

 

 

 

重載的其他場景:比如一個Ajax的封裝,寫函數的時候非常常見

 

function post(url,header,params){
                if(!params){
                    params = header;
                    header = null;  //或者等於undefined也可以
                }
            }
            post('https://imooc.com',{
                a:1,
                b:2
            });
            

 

 

 

 


//一個非常實用的場景,利用重寫的特性,達到預留接口的效果
//比如有方法必須要用子類去實現,如果沒有就報錯

 

class Monster{
                constructor(name,level,model){
                    this.model = model;
                    this.name = name;
                    this.level = level;
                }
                attack(){
                    
                    throw Error('必須由子類來實現`attack`(攻擊)方法')
                }
            }
            
            //模型的映射表
            const ModelMap = {
                '紅眼僵屍':1,
                '南瓜精':2,
                '獨眼蝠':3,
                '綠眼僵屍':4
            }
            
            
            class RedEyeZombie extends Monster{
                //這邊的構造函數不用接收參數,因為它的參數開發者是非常明確地,是不需要外部傳入的
                constructor(){
                    //通過ModelMap['紅眼僵屍']可以訪問到模型對應的ID
                    super('紅眼僵屍',10,ModelMap['紅眼僵屍']);
                }
            }
            class GreenEyeZombie extends Monster{
                constructor(){
                    super('綠眼僵屍',10,ModelMap['綠眼僵屍'])                                                                        
                }
                attack(){
                    console.log('綠眼僵屍發動了攻擊')
                }
            }
            
            const gez = new GreenEyeZombie();
            //覆蓋了父類的attack方法
            gez.attack();
            
            const rez = new RedEyeZombie();
            //子類沒有attack,所以去調用父類的,報錯
            rez.attack();
            
            

 


免責聲明!

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



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