【H2O2|全栈】JS进阶知识(九)ES6(5)
目录
前言
开篇语
准备工作
class类
概念
形式
直接继承
概念
优点
案例
重写
概念
案例
关于重载
结束语
前言
开篇语
本系列博客主要分享JavaScript的进阶语法知识,本期为第九期,依然围绕ES6的语法进行展开。
本期内容为:类,直接继承和重写。
与基础部分的语法相比,ES6的语法进行了一些更加严谨的约束和优化,因此,在之后使用原生JS时,我们应该尽量使用ES6的语法进行代码编写。
准备工作
软件:【参考版本】Visual Studio Code
插件(扩展包):Open in browser, Live Preview, Live Server, Tencent Cloud AI Code Assistant, htmltagwrap
提示:在不熟练的阶段建议关闭AI助手
浏览器版本:Chrome
系统版本: Win10/11/其他非Windows版本
class类
概念
之前我们知道,想要创建一个实例化的对象,可以通过调用它的构造函数去创建。
而且,如果我们想要为这个构造函数声明一些方法,则可以利用原型,并在原型中声明一个构造器(constructor)用来指向原来的构造函数。
现在,ES6提供了一种新的方式——class类,来统筹实现上面的操作。
形式
类使用class关键字声明,比如我们需要创建一个“人类”,就可以这么做——
class Per {}
现在我们为它添加构造函数,或者说构造器,让它能够使用构造函数进行创建——
class Per {
constructor(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
}
如果我们需要为类添加方法,则直接在类中添加即可——
class Per {
constructor(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
height(h) {
console.log(this.name + '身高为' + h + 'cm');
}
}
对于这些使用了this的方法,都是类的实例成员,可以由类的实例化对象创建。
直接继承
概念
继承(inheritance)是面向对象编程(OOP)技术当中的一个概念,在ES6中,使用extends关键字来让一个类继承另一个类。
如果类B“继承自”另一个类A,那么我们就可以把B称为A的子类,而A则为B的父类或超类。
优点
使用继承可以使得子类具有父类的各种属性和方法,而不需要再次编写相同的代码。
在子类继承父类时,可以覆盖父类原来具有的属性和方法,即可以重新定义子类独有的属性,或重写父类的方法,以此实现与父类不同的功能。
这一点和JAVA实际上是非常相像的,因此如果我们学习过JAVA,理解本节的内容将会非常简单。
案例
假设我们现在有一个类GrandPa,这个类的实例化对象gp拥有自己的资产,就像下面这样——
class GrandPa {
constructor(gpMoney) {
this.gpMoney = gpMoney;
}
getGPMoney() {
console.log("GP的" + this.gpMoney + "W");
}
}
let gp = new GrandPa(100);
gp作为家族的最年长的长辈,拥有100W的资产,我们可以使用getGPMoney()来查看这些资产:
gp.getGPMoney();
gp培养他的孩子——由Pa实例化的对象pa,作为家族的继承人,而这位继承人也不负众望,拥有了200W个人资产。
在未来的某一天,弥留之际的gp将pa叫到床前,准备为其宣读遗嘱,我们假设这份遗嘱里声明了gp所有的资产都由pa继承。
那么,类Pa和pa的代码就可以这么写——
class Pa extends GrandPa {
constructor(paMoney, gpMoney) {
super(gpMoney);
this.paMoney = paMoney;
}
getPaMoney() {
console.log("Pa的" + (this.paMoney + this.gpMoney) + "W");
}
}
let pa = new Pa(200, 100);
其中,super()代表超类构造器,相当于在这里执行了GrandPa的this.gpMoney = gpMoney语句。由此,Pa也拥有了GrandPa的资产,实现了遗产的继承。
pa.getPaMoney();
注意super()的参数列表应当与超类构造器保持一致。
pa在悲痛之余,接受了父亲的遗产,也接手了父亲为其留下来的一切。
因此,gp的方法也可以由子代pa调用——
pa.getGPMoney();
重写
概念
重写(Override)是指,子类可以重新定义父类中已有的方法,以改变其行为或实现方式。
当子代想要使用父代的方法名,但是又不想要和父代中的该方法相同,就可以使用方法重写。
注意,重写的方法在调用时遵循就近原则。
案例
pa想要在A市购买一处地产,但是他手上的资产有些不足。因此,每当pa想起这件事情,只能无奈地叹息。
我们将pa的愿望写成下面的方法(Pa的成员方法)——
getHouse() {
console.log("pa在A市没有拿下地产");
}
好在,pa有一个孩子——由Child类创建的cd。这个孩子天赋异禀,具有很强的商业头脑,经过他的不断努力,积累了300W的个人资产。
cd想起了父亲pa的愿望,决定为父亲买下这处地产,在父亲的帮助下,cd最终成功拍下了这处地产。
我们在Child中重写父亲pa的getHouse()方法——
class Child extends Pa {
constructor(cdMoney, paMoney, gpMoney) {
super(paMoney, gpMoney);
this.cdMoney = cdMoney;
}
getHouse() {
console.log("cd在A市成功拿下地产,实现了父亲的愿望");
}
}
let cd = new Child(300, 200, 100);
现在,我们分别让pa和cd调用这两个同名的方法——
pa.getHouse();
cd.getHouse();
关于重载
注意,ES6暂时还没有提供重载(Overload)的方法。
当我们在同一个类中使用同一个方法名重新声明方法后,新声明的方法会覆盖原来的方法。
所以,像JAVA那种直接可以同一个方法设置不同数量的参数,不能直接仿照JAVA的重载方式去做,但其实是可以有类似的方法实现的,这里就不扩展了。
结束语
本期内容到此结束。关于本系列的其他博客,可以查看我的JS进阶专栏。
在全栈领域,博主也只不过是一个普通的萌新而已。本系列的博客主要是记录一下自己学习的一些经历,然后把自己领悟到的一些东西总结一下,分享给大家。
文章全篇的操作过程都是笔者亲自操作完成的,一些定义性的文字加入了笔者自己的很多理解在里面,所以仅供参考。如果有说的不对的地方,还请谅解。
==期待与你在下一期博客中再次相遇==
——临期的【H2O2】