传智播客旗下技术交流社区北京校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 不二晨 黑马程序员官方团队   /  2019-1-13 12:54  /  61 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

接昨天继续以class类作为学习对象,回顾面向对象开发有三要素。

继承,子类继承父类
封装,数据的权限和保密
多态,同一接口不同实现
今天先复习下继承相关。

class可以通过extends关键字来实现子类继承父类。

class People{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }

    static speak(){     //类的静态方法
        console.log('I am speaking.');
    }

    selfIntro(){
        console.log(`Hello, my name is ${this.name}, i'm ${this.age} years old.`);
    }
}

let nitx = new People('nitx', 30);
nitx.selfIntro();
People.speak();

class Student extends People{
    constructor(name, age, score){
        super(name, age);   // 调用父类的constructor(x, y)
        this.score = score;
    }

    showScore(){
        console.log(`${this.name}'s score is ${this.score}, this guy's age is ${this.age}.`);
        return super.selfIntro();
    }
}

let sxm = new Student('sxm', 21, 'A1');
sxm.showScore();
Student.speak();
/**
打印:
Hello, my name is nitx, i'm 30 years old.
I am speaking.
sxm's score is A1, this guy's age is 21.
Hello, my name is sxm, i'm 21 years old.
I am speaking.
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
上例可以看到,子类Student的constructor方法和showScore方法中,都用到了super关键字,它表示的是父类的构造函数,用来新建父类的this对象,注意,super虽然代表了父类的构造函数,但是返回的是子类的实例,即super内部的this指的是子类,因此super()在这里相当于A.prototype.constructor.call(this)。

子类必须在constructor方法中调用super方法,否则新建实例时报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。
ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。

如果子类没有定义constructor方法,这个方法会被默认添加,也就是说,不管有没有显式定义,任何一个子类都有constructor方法。

父类的静态方法也会被子类所继承。

这里有个地方需要注意下,在子类的constructor构造函数中,必须先调用super方法,才能使用this,否则就会报错。因为子类实例的构建是基于父类实例的,所以必须先调用super方法获取父类的实例。

class Student extends People{
    constructor(name, age, score){
        this.score = score;
        super(name, age);   // 调用父类的constructor(x, y)
    }

    /*
    原型方法(实例方法)
    */
}
//打印错误信息
/*
ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
子类的实例对象同时是子类和父类这两个类的实例,与es5的行为一致。

console.log(sxm instanceof Student);    //true
console.log(sxm instanceof People);     //true
1
2
上面是知道父类和子类的继承关系的,但有时并不会完全清楚,此时就需要一个方法帮助开发者判断父类子类的关系Object.getPrototypeOf()

console.log(Object.getPrototypeOf(Student));    //[Function: People]
console.log(Object.getPrototypeOf(Student) === People);    //true
1
2
继承的优势:

People是父类,公共的,不仅仅服务于Student类
继承可将公共方法抽象出来,提高利用,减少冗余
---------------------
【转载,仅作分享,侵删】
作者: 一期一会
原文:https://blog.csdn.net/qq_34832846/article/details/86221424


分享至 : QQ空间
收藏

1 个回复

倒序浏览
奈斯
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马