JavaScript 使用 extends 继承 class
JavaScript 的 extends
关键字是在 ES6 中引入的, 也包含连同一起使用的 super
关键字, 可以通过它们来进行 class
的继承
比如我们有一个名为 Book
的类, 包含 “书名” 与 “作者” 两个属性,以及一个书籍介绍的方法 getInfo()
class Book {
constructor(title, author){
this.title = title;
this.author = author;
}
// 获取书籍介绍
getInfo(){
return "这本书叫《" + this.title
+ "》,作者是" + this.author;
}
}
更多关于 class
的定义: JS 如何使用 class 关键字定义类
使用 extends 进行继承
我们创建一个历史书籍类,名为 HistoryBook
,通过 extends
关键字让它继承自 Book
类 ,并为它添加一个 “朝代” 属性 dynasty
class HistoryBook extends Book {
constructor(title, author, dynasty){
super(title, author);
this.dynasty = dynasty;
}
}
此处的 super
关键字用于显式调用父类构造函数 constructor
实例化子类
我们来尝试通过实例化一个 HistoryBook
类,看能否获得它的父类属性 title
与 author
以及父类方法 getInfo()
let book = new HistoryBook("水浒传", "施耐庵", "北宋");
console.log(book);
console.log(book.getInfo());
打印如下:
HistoryBook { title: '水浒传', author: '施耐庵', dynasty: '北宋' }
这本书叫《水浒传》,作者是施耐庵
可以看到,通过实例化 HistoryBook
得到的 book
对象,包含了自身属性 dynasty
,也包含父级属性 title
与 author
,以及父级方法 getInfo()
函数重写
如果子类的方法名与父级方法名一致,父级的将会被覆盖。比如我们在 HistoryBook
中定义一个与父级 Book
一致的函数名 getInfo()
class HistoryBook extends Book {
/* ... 此处省略了一些代码 */
// 重写父级的 getInfo 方法
getInfo(){
return "这本历史书叫《" + this.title
+ "》,作者是" + this.author
+ ",年代为:" + this.dynasty;
}
}
参照 #实例化子类 步骤实例化 book 对象后执行:
console.log(book.getInfo());
调用的是重写后的函数,打印如下:
这本历史书叫《水浒传》,作者是施耐庵,年代为:北宋
子类中的 this/super
在某些情况下,我们重写了父类的方法后,任然想要调用父类已被覆盖的方法,这时候可以使用 super
关键字。 例如,我们需要一个书籍的简短介绍的方法 getBriefInfo()
,想通过调用父级的 getInfo()
实现
class HistoryBook extends Book {
/* ... 此处省略了一些代码 */
// 重写父级的 getInfo (书籍介绍)方法
getInfo(){
return "这本历史书叫《" + this.title
+ "》,作者是" + this.author
+ ",年代为:" + this.dynasty;
}
// 书籍简短介绍
getBriefInfo(){
return super.getInfo();
}
}
在文章开始时,我们在 HistoryBook
的构造函数 constructor
中使用过一次 super
,那里我们将它当作函数来使用,作用是显示的调用父类构造函数。 而此处的 super
我们把它当作 “对象” 来使用,在这里它指代的是父类中的 this
子类中的 this
与常规类一样,都是指代类的实例本身
我们继续下一步,参照 #实例化子类 步骤实例化 book 对象后执行:
console.log(book.getBriefInfo());
可以看到,打印的是父级的介绍
这本书叫《水浒传》,作者是施耐庵
所以这里的 super.getInfo()
表示调用父级的 getInfo()
方法
完整代码
// 书籍基类
class Book {
constructor(title, author){
this.title = title;
this.author = author;
}
// 获取书籍介绍
getInfo(){
return "这本书叫《" + this.title
+ "》,作者是" + this.author;
}
}
// 历史书籍,继承自 Book
class HistoryBook extends Book {
constructor(title, author, dynasty){
super(title, author);
this.dynasty = dynasty;//朝代
}
// 重写父级的 getInfo 方法,增加了年代的描述
getInfo(){
return "这本历史书叫《" + this.title
+ "》,作者是" + this.author
+ ",年代为:" + this.dynasty;
}
// 书籍简短介绍,通过调用父级 getInfo 实现
getBriefInfo(){
return super.getInfo();
}
}
// 实例化 HistoryBook
let book = new HistoryBook("水浒传", "施耐庵", "北宋");
console.log(book);
console.log(book.getInfo());
console.log(book.getBriefInfo());