类的实现与继承

类class

  在 ES6 之前,JavaScript 不能像其它语言(PHP,Java)等有完整的类支持;采用了原型链实现了面向对象的功能,但从 ES6 开始,提供了真正的类语法。它可以看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程的语法。

   通过 class 关键字定义类:
//匿名
let c=class{
    constructor(val){
        this.val=val;
    }
}
//命名
class c{
    constructor(val){
        this.val=val;
    }
}

 constructor 是类的构造函数,创建类的实例化对象时被调用,用来接受参数。

    console.log(new c("123"));    

  

  

console.log(typeof c); //function
console.log(c === c.prototype.constructor); //true

   class 的本质还是一个方法。不可以重复声明。

   class c { }     ---     function c() {}  

  其本身指向的就是构造函数,所以可以认为类其实就是构造函数的另一种写法。
 
 
  创建一个Person类:
class Person {
   // 方法间不须加 ,分分隔
// 构造方法 constructor(name) { this.name = name; } //普通方法 不要加function run() { return "类的方法:"+ this.name; } } // 实例化Person对象 let p = new Person("li"); // 执行run方法 console.log(p.run()); //类的方法:li
 
 类的属性,可以在类外获取赋值,
console.log(p.name); //li
p.name = "wang";
console.log(p.name); //wang
  这个其实是在类外创建了一个属性,进行获取赋值,概念与对象类似 ︾:
let obj={};
obj.name="li";
console.log(obj.name); //li

  若不想在外部被访问,可以将成员属性封装为私有属性。

class Person {
    // 成员属性 -(封装)-> 私有属性
    // 将name作成私有成员属性
    // 提案 浏览器暂不支持
    #name;

    // 构造函数
    constructor(name) {
        this.#name = name;
    } 
    // 普通方法
    run() {
        return "类的方法:"+ this.#name;
    }
} 

   

 

  对私有属性的读取、赋值,需要使用 get()、set()两个方法 :

get name2() {
    return this.#name;
}
set name2(value) {
    this.#name = value;
}
console.log(p.name2); //li
p.name2 = "wang";
console.log(p.name2); //wang

    注:写在类中,二者必须同时、同级出现

 

 继承

  通过使用 extends 关键字实现子类继承父类

 父类:

class Person {
    //构造函数
    constructor(name) {
        this.name = name;
    }
    //get set
    get user() {
        return this.name;
    }
    set user(value) {
        this.name = value;
    }
   //方法 run() {
return "name : " + this.name; } // 静态属性 方法 static gender = "男"; static go() { return "GO GO GO " + Person.gender; } }

 子类:

class Children extends Person {

}

  一旦子类使用关键字 extends 继承了父类,子类就可以继承父类所有,现在子类里面虽然什么都没有写,但可以直接使用父类的构造、属性、方法等等。

let c = new Children("li", 100);
// 构造
console.log(c); //Children {name: 'li'}
//属性
console.log(c.name); //li
//方法
console.log(c.run()); //name : li
//get、set
console.log(c.name); //li
c.user = "wang";
console.log(c.name); //wang
//静态属性、方法
console.log(Children.gender); //男
console.log(Children.go()); //GO GO GO 男

 

 继承之后,一般需要覆写父类,对子类进行增强。

 以覆写构造和方法为例:

class Children extends Person {
    // 覆写构造
    constructor(name, age) {
      super(name);
      this.age = age;
    }
    // 覆写方法
    run() {
        return super.run() +" age:"+ this.age;
    }
}
let c = new Children("li", 100);
console.log(c);
console.log(c.run());

 

 

  super 关键字

 在调用的时候有两种情况:

      

  • super作为函数调用时,代表父类的构造函数。

  如果子类调用constructor,那么子类必须在coonstructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。

  • super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

    

 

posted @ 2021-12-02 13:06  十七日尾  阅读(272)  评论(0)    收藏  举报