2.继承

1.继承的基本使用

  • es6中有继承,通过extends关键字定义,ts也支持,我们也可以通过extends关键字实现继承,

  • 使用继承后,子类会拥有父类所有的方法和属性

例子

使用继承之前

(function (){

// 定义一个狗的类
class Dog {
// 定义属性
name: string;
age: number;

// 创建构造函数
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}

// 定义方法
sayHello(){
console.log('汪汪汪!');
}
}

// 定义一个表示猫的类
class Cat {
name: string;
age: number;

constructor(name: string, age: number) {
this.name = name;
this.age = age;
}

sayHello(){
console.log('喵喵喵!');
}
}

const dog = new Dog('旺财', 5);//实例化类
const cat = new Cat('咪咪', 3);//实例化类
console.log(dog);
console.log(cat);
})();
  • 由上述的代码,我们可以发现,无论是狗的类还是猫的类,他们基本都有一样的属性和相似的方法,但是我们却创建了两个类,这样代码就会显得非常的冗余,此时我们就可以使用继承来提高代码的执行效率

使用继承之后

(function (){
// 定义一个Animal类(父类)
class Animal{
// 定义属性
name: string;
age: number;

// 创建构造函数
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}

// 定义方法
sayHello(){
console.log('动物在叫~');
}
}

/*
* Dog extends Animal
* - 此时,Animal被称为父类,Dog被称为子类
* - 使用继承后,子类将会拥有父类所有的方法和属性
* - 通过继承可以将多个类中共有的代码写在一个父类中,
* 这样只需要写一次即可让所有的子类都同时拥有父类中的属性和方法
* 如果希望在子类中添加一些父类中没有的属性或方法直接加就行
* - 如果在子类中添加了和父类相同的方法,则子类方法会覆盖掉父类的方法
* 这种子类覆盖掉父类方法的形式,我们称为方法重写
*
* */
// 1.定义一个表示狗的类
// 使Dog类继承Animal类(子类)
class Dog extends Animal{
// 在子类中添加父类没有的方法或属性
run(){
console.log(`${this.name}在跑~~~`);
}

// 在子类中改写父类中的方法
sayHello() {
console.log('汪汪汪汪!');
}
}

// 定义一个表示猫的类
// 2.使Cat类继承Animal类(子类)
class Cat extends Animal{

// 在子类中改写父类中的方法
sayHello() {
console.log('喵喵喵喵!');
}
}

// 类的实例化
const dog = new Dog('旺财', 5);
const cat = new Cat('咪咪', 3);

// 输出结果
console.log(dog);
console.log(cat);
})();

结果展示:

image

Super关键字

  • super代表的就是当前的父类

在类的方法中

  • 在类的方法中super直接表示父类
  • 我们可以通过super.父类的方法调用父类的方法

代码展示:

(function () {
// 1.创建一个父类(Animal)
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
sayHello() {
console.log('动物在叫~');
}
}

// 2.创建一个子类(Dog)来继承父类(Animal)
class Dog extends Animal{
age: number;
sayHello() {
// 在类的方法中 super就表示当前类的父类
super.sayHello();//可以直接通过super关键字来调用父类的属性或方法
}
}

// 3.子类的实例化
const dog = new Dog('旺财');
dog.sayHello();//成功输出:动物在叫~
})();

结果展示:

image

构造函数中(比较常用)

  • 在构造函数中super()表示父类的构造函数
  • 如果在子类中写了构造函数,就必须调用父类的构造函数
    • 原因:
      • 我们都知道,子类在继承父类的时候是存在有函数重写这一说法的,也就是说,当我们在子类当中调用构造函数的时候就会覆盖掉我们从父类当中继承过来的构造函数,父类的构造函数不执行,这时的子类就不能从父类中继承属性或方法了,因此我们需要重新调用一下父类的构造函数,也就是重新调用一次super(父类中内置的属性)来重新激活父类的继承

代码展示:

(function () {
// 1.创建一个父类(Animal)
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
sayHello() {
console.log('动物在叫~');
}
}

// 2.创建一个子类(Dog)来继承父类(Animal)
class Dog extends Animal{
// 此时我们想通过构造函数的方式给子类添加父类中没有的属性
age: number;
/*
原因:我们都知道,子类在继承父类的时候是存在有函数重写这一说法的,也就是说,当我们在
子类当中调用构造函数的时候就会覆盖掉我们从父类当中继承过来的构造函数,父类的
构造函数不执行,这时的子类就不能从父类中继承属性或方法了,因此我们需要重新调用
一下父类的构造函数,也就是重新调用一次super(父类中内置的属性)来重新激活父类的继承
*/
constructor(name: string, age: number) {
// 如果在子类中写了构造函数,在子类构造函数中必须对父类的构造函数进行调用
super(name); // 调用父类的构造函数
this.age = age;
}
}

// 实例化子类
const dog = new Dog('旺财', 3);
console.log(dog);//成功输出新增属性以及继承父类后的子类实例
})();

结果展示:

image