接昨天继续以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. */
上例可以看到,子类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 */
子类的实例对象同时是子类和父类这两个类的实例,与es5的行为一致。
console.log(sxm instanceof Student); //true console.log(sxm instanceof People); //true
上面是知道父类和子类的继承关系的,但有时并不会完全清楚,此时就需要一个方法帮助开发者判断父类子类的关系Object.getPrototypeOf()
console.log(Object.getPrototypeOf(Student)); //[Function: People] console.log(Object.getPrototypeOf(Student) === People); //true
继承的优势:
People
是父类,公共的,不仅仅服务于Student
类继承可将公共方法抽象出来,提高利用,减少冗余
作者:一期一会
链接:https://blog.csdn.net/qq_34832846/article/details/86221424
来源:CSDN
著作权归作者所有,转载请联系作者获得授权,切勿私自转载。