• 226 对象与类 之 类: class 创建类,constructor构造函数, 类创建添加属性和方法,类的继承extends,super访问父类的方法,this 指向


    • 在 ES6 中新增加了类的概念,可以使用 class 关键字声明一个类,之后以这个类来实例化对象。
    • 类抽象了对象的公共部分,它泛指某一大类(class)
    • 对象特指某一个,通过类实例化一个具体的对象
    • 面向对象的思维特点:
      1. 抽取(抽象)对象共用的属性和行为组织(封装)成一个类(模板)
      2. 对类进行实例化, 获取类的对象


    2.2.1 创建类

        //  (1) 通过class 关键字创建类, 类名我们还是习惯性定义首字母大写
        //  (2) 类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象
        //  (3) constructor函数: 只要 new 生成实例时, 就会自动调用这个函数, 如果我们不写这个函数,类也会自动生成这个函数
        //  (4) 生成实例,new 不能省略
        //  (5) 最后注意语法规范, 创建类 类名后面不要加小括号, 生成实例 类名后面加小括号, 构造函数不需要加function
    

    1. 语法:
    //步骤1 使用class关键字
    class name {
      // class body
    }     
    //步骤2使用定义的类创建实例  注意:类必须使用 new 实例化对象
    var xx = new name();     
    
    1. 示例
     // 1. 创建类 class  创建一个 明星类
     class Star {
       // 类的共有属性放到 constructor 里面
       constructor(name, age) {
       this.name = name;
       this.age = age;
       }
     }
       // 2. 利用类创建对象 new
       var ldh = new Star('刘德华', 18);
       console.log(ldh);
    

    以上代码运行结果:

    通过结果我们可以看出,运行结果和使用构造函数方式一样

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    
    <body>
        <script>
            //(1) 通过class 关键字创建类, 类名我们还是习惯性定义首字母大写
            //(2) 类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象
            //(3) constructor函数: 只要 new 生成实例时, 就会自动调用这个函数, 如果我们不写这个函数,类也会自动生成这个函数
            //(4) 生成实例,new 不能省略
            //(5) 最后注意语法规范, 创建类 类名后面不要加小括号, 生成实例 类名后面加小括号, 构造函数不需要加function
    
            // 1. 创建类 class  创建一个 明星类
            class Star {
                constructor(uname, age) {
                    this.uname = uname;
                    this.age = age;
                }
            }
    
            // 2. 利用类创建对象 new
            var ldh = new Star('刘德华', 18);
            var zxy = new Star('张学友', 20);
            console.log(ldh);
            console.log(zxy);
            console.log(ldh.uname, ldh.age);  // 刘德华 18
            console.log(zxy.uname, zxy.age);  // 张学友 20
        </script>
    </body>
    
    </html>
    

    2.2.2 类创建添加属性和方法

     // 1. 创建类 class  创建一个类
    class Star {
        // 类的共有属性放到 constructor 里面 constructor是 构造器或者构造函数
        constructor(uname, age) {
          this.uname = uname;
          this.age = age;
        }//------------------------------------------->注意,方法与方法之间不需要添加逗号
        sing(song) {
          console.log(this.uname + '唱' + song);
        }
    }
    // 2. 利用类创建对象 new
    var ldh = new Star('刘德华', 18);
    console.log(ldh); // Star {uname: "刘德华", age: 18}
    ldh.sing('冰雨'); // 刘德华唱冰雨
    

    以上代码运行结果:


    注意哟:

    1. 通过class 关键字创建类, 类名我们还是习惯性定义首字母大写
    2. 类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象
    3. constructor 函数 只要 new 生成实例时,就会自动调用这个函数, 如果我们不写这个函数,类也会自动生成这个函数
    4. 多个函数方法之间不需要添加逗号分隔
    5. 生成实例 new 不能省略
    6. 语法规范, 创建类 类名后面不要加小括号,生成实例 类名后面加小括号, 构造函数不需要加function

    2.2.3 类的继承

    1. 语法
    // 父类
    class Father{   
    } 
    
    // 子类继承父类
    class  Son  extends Father {  
    }       
    
    1. 示例
    class Father {
          constructor(surname) {
            this.surname= surname;
          }
          say() {
            console.log('你的姓是' + this.surname);
           }
    }
    
    class Son extends Father{  // 这样子类就继承了父类的属性和方法
    }
    var damao= new Son('刘');
    damao.say();      //结果为 你的姓是刘
    

    以上代码运行结果:

    • 子类使用super关键字访问父类的方法

      //定义了父类
      class Father {
         constructor(x, y) {
         this.x = x;
         this.y = y;
         }
         sum() {
         console.log(this.x + this.y);
      	}
       }
      //子元素继承父类
          class Son extends Father {
         		 constructor(x, y) {
          		super(x, y); //使用super调用了父类中的构造函数
          	}
          }
          var son = new Son(1, 2);
          son.sum(); //结果为3
      

      注意:

      1、继承中, 如果实例化子类输出一个方法, 先看子类有没有这个方法, 如果有就先执行子类的

      2、继承中, 如果子类里面没有, 就去查找父类有没有这个方法,如果有, 就执行父类的这个方法(就近原则)

      3、如果子类想要继承父类的方法,同时在自己内部扩展自己的方法,利用super 调用父类的构造函数,super 必须在子类this之前调用

      4、时刻注意this的指向问题,类里面的共有的属性和方法一定要加this使用:

      ​ 【constructor 里面的this指向实例对象,方法里面的this 指向这个方法的调用者,两者不一定相同。】

      ​ (1) constructor中的this指向的是new出来的实例对象
      ​ (2) 自定义的方法,一般也指向的new出来的实例对象
      ​ (3) 绑定事件之后,【方法里面的】this指向的就是触发事件的事件源

      5、在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象


       // 父类有加法方法
       class Father {
         constructor(x, y) {
         this.x = x;
         this.y = y;
         }
         sum() {
         console.log(this.x + this.y);
       }
       }
       // 子类继承父类加法方法 同时 扩展减法方法
       class Son extends Father {
         constructor(x, y) {
         // 利用super 调用父类的构造函数 super 必须在子类this之前调用,放到this之后会报错
       super(x, y);
       this.x = x;
       this.y = y;
      
        }
        subtract() {
        console.log(this.x - this.y);
        }
      }
      var son = new Son(5, 3);
      son.subtract(); //2
      son.sum();//8
      

      以上代码运行结果为:


    demo:类的继承
    
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    
    <body>
        <script>
            // 1. 类的继承
            // class Father {
            //     constructor() {
    
            //     }
            //     money() {
            //         console.log(100);
    
            //     }
            // }
            // class Son extends Father {
    
            // }
            // var son = new Son();
            // son.money();
    
    
            class Father {
                constructor(x, y) {
                    this.x = x;
                    this.y = y;
                }
                sum() {
                    console.log(this.x + this.y);
                }
            }
            class Son extends Father {
                constructor(x, y) {
                    // (1)调用了父类中的构造函数; (2)在子类的constructor方法中,调用父类的constructor,只需写 super(参数列表) 即可,不能写super.constructor(参数列表).
                    super(x, y); //调用了父类中的构造函数
                }
            }
            var son = new Son(1, 2);
            var son1 = new Son(11, 22);
            son.sum();
            son1.sum();
        </script>
    </body>
    
    </html>
    
    demo: 04-super关键字调用父类普通函数(1)
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    
    <body>
        <script>
            // 继承中的属性或者方法查找原则: 就近原则
            // 1. 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
            // 2. 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)
    
            // super 关键字调用父类普通函数
            class Father {
                say() {
                    return '我是爸爸';
                }
            }
    
            class Son extends Father {
                say() {
                    // console.log('我是儿子');
                    // (1)和python的super()类的使用方式一样。(2)super.say() 就是调用父类中的普通函数 say()
                    console.log(super.say() + '的儿子'); // 我是爸爸的儿子
                }
            }
            var son = new Son();
            son.say();
        </script>
    </body>
    
    </html>
    
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    
    <body>
        <script>
            // 父类有加法方法
            class Father {
                constructor(x, y) {
                    this.x = x;
                    this.y = y;
                }
                sum() {
                    console.log(this.x + this.y);
                }
            }
    
            // 子类继承父类加法方法 同时 扩展减法方法
            class Son extends Father {
                constructor(x, y) {
                    // 利用super 调用父类的构造函数
                    // super 必须在子类this之前调用
                    super(x, y);
                    // 经测试,下面2行代码注释掉,结果一样,但是最好写上。父类Father中的constructor函数必须写上赋值语句,否则结果是NaN
                    this.x = x;
                    this.y = y;
                }
    
                subtract() {
                    console.log(this.x - this.y);
                }
            }
    
            var son = new Son(5, 3);
            son.subtract();  // 2
            son.sum();  // 8
        </script>
    </body>
    
    </html>
    
    重点案例:使用类注意事项
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    
    <body>
        <button>点击</button>
        <script>
            var that;
            var _that;
            class Star {
                constructor(uname, age) {
                    // constructor 里面的this 指向的是 创建的实例对象
                    that = this;
                    console.log(this);
    
                    this.uname = uname;
                    this.age = age;
                    // this.sing();
                    // 这个btn属于实例对象ldh的,this指向ldh,所以写成this.btn
                    this.btn = document.querySelector('button');
                    // (1)告诉别人,点击了哪一个按钮,是点击了ldh的按钮,所以加上this;(2)this.sing 只是一个函数,this是在constructor方法中,还是指向实力对象;(3)this.sing后面不要加();(4)把this.sing看做一个整体,它就是实例对象的方法,就是一个普通的函数。
                    this.btn.onclick = this.sing;
                }
    
                sing() {
                    // 这个sing方法里面的this 指向的是 btn 这个按钮,因为这个按钮调用了这个函数
                    console.log(this); //  <button>点击</button>
                    console.log(that.uname); // 刘德华; that里面存储的是constructor里面的this
                }
    
                dance() {
                    // 这个dance里面的this 指向的是实例对象 ldh 因为ldh 调用了这个函数
                    _that = this;
                    console.log('dance中的this:', this); // (1)dance中的this: Star {uname: "刘德华", age: undefined, btn: button}; (2)注意这里新增的btn: button。
                }
            }
    
            var ldh = new Star('刘德华');
            console.log(that === ldh); // true
            ldh.dance(); // 
            console.log(_that === ldh); // true
    
            // 1. 在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象
            // 2. 类里面的共有的属性和方法一定要加this使用.
        </script>
    </body>
    
    </html
    
  • 相关阅读:
    设计模式之单例模式
    Java反射之调用内部类
    Java反射之修改常量值
    myBatis之入门示例
    eclipse创建maven工程
    java核心卷轴之集合
    java核心卷轴之泛型程序设计
    sublime常用快捷键
    sublime使用package control安装插件
    sublime使用技巧之添加到右键菜单、集成VI
  • 原文地址:https://www.cnblogs.com/jianjie/p/12217178.html
Copyright © 2020-2023  润新知