09 如何用 class 实现继承
- constructor 构造函数
- 属性
- 方法
javascript
// 定义一个基类 Person,它有一个构造函数 constructor,一个实例属性 name 和一个实例方法 introduceSelf
class Person {
// 构造函数
constructor(name) {
this.name = name // 实例属性
}
// 实例方法
introduceSelf() {
console.log(`Hi! I'm ${this.name}`)
}
}javascript
// 定义一个继承自 Person 的子类 Professor,并添加了一个新的属性 teaches,覆盖了 introduceSelf 方法,并添加了一个新的方法 grade。
class Professor extends Person {
constructor(name, teaches) {
super(name) // 调用父类的构造函数
this.teaches = teaches // 新的实例属性
}
// 覆盖父类的方法
introduceSelf() {
console.log(`My name is ${this.name}, and I will be your${this.teaches} professor.`)
}
// 新的方法
grade(paper) {
const grade = Math.floor(Math.random() * (5 - 1) + 1)
console.log(grade)
}
}javascript
// 使用类
const giles = new Person('Giles')
giles.introduceSelf() // 输出:Hi! I'm Giles
const walsh = new Professor('Walsh', 'Psychology')
walsh.introduceSelf() // 输出:My name is Walsh, and I will be your Psychology professor
walsh.grade('my paper') // 随机输出一个分数extends关键字用于创建一个继承自另一个类的子类super关键字用于调用父类的方法或构造函数- 子类可以覆盖父类的方法,也可以添加新的方法
constructor 构造函数
constructor是一个特殊的方法,用于在创建类实例时进行初始化。- 在创建类的实例时,会自动调用
constructor方法。 - 它通常用于设置实例的初始属性值。
- 每个类只能有一个构造函数,如果没有显式定义,JavaScript 会提供一个默认的构造函数。
语法
javascript
class ClassName {
constructor(parameters) {
// 构造函数体
}
}用途
- 初始化对象的实例属性。
- 可以接受参数,并在创建对象时传递这些参数。
### 代码示例
javascript
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
}
const john = new Person('John', 30)
console.log(john.name) // 输出:John
console.log(john.age) // 输出:30属性
- 在
class中,属性是与特定实例关联的数据。 - 它们通常在
constructor中初始化。 - ECMAScript 2019 (ES10) 引入了类字段的概念,允许直接在类定义中声明属性。
在 JavaScript 类中,属性可以是实例属性或静态属性。
- 实例属性:
- 属于类的每个实例。
- 在类的构造函数或方法中通过
this关键字定义。
- 静态属性:
- 属于类本身,而不是类的实例。
- 使用
static关键字定义。
javascript
class Person {
// 属性初始化
name = ''
age = 0
constructor(name, age) {
this.name = name // 实例属性
this.age = age // 实例属性
}
// 静态属性
static nationality = 'China'
}
const jane = new Person('wwvl', 25)
console.log(jane.name) // 输出:wwvl
console.log(jane.age) // 输出:25方法
- 类方法是类的功能。
- 它们定义在类的原型上,因此所有实例共享这些方法。
- 方法可以访问类实例的属性和其他方法。
方法是与类关联的函数,可以是实例方法或静态方法。
- 实例方法:
- 属于类的每个实例。
- 可以通过类的实例来调用。
- 在方法内部可以通过
this访问实例属性。
- 静态方法:
- 属于类本身,而不是类的实例。
- 使用
static关键字定义。 - 不能通过类的实例调用,只能通过类本身调用。
- 在静态方法内部不能直接访问
this,因为静态方法不与类的任何特定实例相关联。
javascript
class Person {
constructor(name, age) {
this.name = name // 实例属性
this.age = age
}
// 静态属性
static nationality = 'China'
// 定义实例方法 greet
greet() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`)
}
// 定义实例方法 greet
haveBirthday() {
this.age += 1
console.log(`Happy Birthday! Now I am ${this.age} years old.`)
}
// 定义静态方法 sayHello
static sayHello() {
console.log('Hello, world!')
}
// 定义静态方法 getNationality
static getNationality() {
return Person.nationality
}
}
const bob = new Person('wwvl', 40)
// 调用实例方法
bob.greet() // 输出:Hello, my name is wwvl and I am 40 years old.
bob.haveBirthday() // 输出:Happy Birthday! Now I am 41 years old.
// 调用静态方法
Person.sayHello() // 输出:Hello, world!
console.log(Person.getNationality()) // 输出:China练习
js
// 定义一个父类 Animal
class Animal {
// 构造函数,用于初始化属性
constructor(name, age) {
this.name = name // 定义一个属性 name
this.age = age // 定义一个属性 age
}
// 定义一个方法用于描述动物
describe() {
return `${this.name} is ${this.age} years old.`
}
}js
// 定义一个子类 Dog,继承自 Animal
class Dog extends Animal {
// 构造函数,用于初始化属性
constructor(name, age, breed) {
// 调用父类的构造函数
super(name, age)
this.breed = breed // 定义一个属性 breed
}
// 定义一个方法用于描述狗的品种
describeBreed() {
return `${this.name} is a ${this.breed}.`
}
// 重写父类的方法
describe() {
return `${super.describe()} It is a ${this.breed}.`
}
}js
// 创建一个 Animal 的实例
const animal = new Animal('Lion', 5)
console.log(animal.describe()) // 输出:Lion is 5 years old.
// 创建一个 Dog 的实例
const dog = new Dog('Buddy', 3, 'Golden Retriever')
console.log(dog.describe()) // 输出:Buddy is 3 years old. It is a Golden Retriever.
console.log(dog.describeBreed()) // 输出:Buddy is a Golden Retriever.定义父类 Animal:
constructor函数用于初始化name和age属性。describe方法用于返回描述name和age的字符串。
定义子类 Dog:
- 使用
extends关键字继承Animal类。 constructor函数除了接收name和age外,还接收breed,并调用super(name, age)初始化父类的属性。describeBreed方法用于返回描述breed的字符串。- 重写
describe方法,调用super.describe()获取父类方法的返回值,并在其基础上添加breed的描述。