Skip to content

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 函数用于初始化 nameage 属性。
  • describe 方法用于返回描述 nameage 的字符串。

定义子类 Dog:

  • 使用 extends 关键字继承 Animal 类。
  • constructor 函数除了接收 nameage 外,还接收 breed,并调用 super(name, age) 初始化父类的属性。
  • describeBreed 方法用于返回描述 breed 的字符串。
  • 重写 describe 方法,调用 super.describe() 获取父类方法的返回值,并在其基础上添加 breed 的描述。