zoukankan      html  css  js  c++  java
  • 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();
                
                
  • 相关阅读:
    常见规格液晶显示器尺寸/点距/分辨率
    Disk genius(Diskgenius)修复硬盘分区表
    IIS上注册.Net
    PowerDesigner中如何导入表结构
    关于VS命名空间的引用
    启动Word时出现“复制文件或文件夹时出错"对话框?
    能够删除的安卓(Android)系统自带程序详细列表和说明
    五种方法 解决Windows最大终端连接数
    查看本机打开的端口
    RAID技术概述
  • 原文地址:https://www.cnblogs.com/rickdiculous/p/13727529.html
Copyright © 2011-2022 走看看