视频位置 TypeScript快速梳理_下篇 0:18:52

概述

抽象类是⼀种⽆法被实例化的类,专⻔⽤来定义类的结构和⾏为,类中可以写抽象⽅法,也可以写具体实现。抽象类主要⽤来为其派⽣类提供⼀个基础结构,要求其派⽣类必须实现其中的抽象⽅法。

将上面内容翻译之后就是:

术语 白话
⽆法被实例化 不能用new关键字调用
结构和⾏为 属性和方法
抽象⽅法 没有具体的实现
为其派⽣类提供⼀个基础结构 为了让其它类继承它
必须实现 如果抽象类中有抽象方法,那么派生类必须实现它

简记

抽象类不能实例化,其意义是可以被继承,抽象类⾥可以有普通⽅法、也可以有抽象⽅法

理解

通过以下场景,理解抽象类:

我们定义⼀个抽象类 Package ,表示所有包裹的基本结构,任何包裹都有重量属性 weight ,包裹都需要计算运费。但不同类型的包裹(如:标准速度、特快专递)都有不同的运费计算⽅式,因此⽤于计算运费的 calculate ⽅法是⼀个抽象⽅法,必须由具体的⼦类来实现。

//abstract 定义抽象类
abstract class Package {
    //构造函数
    constructor(public weight: number) { }

    //抽象⽅法:⽤来计算运费,不同类型包裹有不同的计算⽅式
    //抽象方法不能写函数体。 例如: 不能写为 abstract calculate(){}
    //抽象方法只能规定形式。
    //例如:
    // 规定 calculate 是抽象方法
    // 规定 不接收参数
    // 规定 返回类型为 number
    abstract calculate(): number

    //具体方法
    //通⽤⽅法:打印包裹详情
    printPackage() {
        //注意: 此处调用了抽象方法 calculate() 这也就是为什么抽象类不能new的原因,如果你
        //       new了,调用 printPackage()的时候,怎么去调用抽象方法calculate()呢?
        //     没办法调用calculate(),它还没有实现。
        console.log(`包裹重量为: ${this.weight}kg,运费为: ${this.calculate()}元`);
    }
}
//错误写法: 因为Package()是抽象类,所以不能new
//const p1 = new Package()

我们继续写一个 StandardPackage 类继承自 Package ,实现 calculate ⽅法:

// 标准包裹StandardPackage类 继承自 Package类
class StandardPackage extends Package {
    constructor(
        weight: number,
        //简写形式中 在参数中必须加public,不能省略。
        public unitPrice: number // 每公⽄的固定费率。  假设标准包裹有自己独有的属性unitPrice单位价格
    ) {
        super(weight)
    }

    //实现父类的抽象⽅法:计算运费
    calculate(): number {
        return this.weight * this.unitPrice;
    }
}

//测试:
// 创建标准包裹实例
const s1 = new StandardPackage(10,5)
s1.printPackage()

上面的计算方法还是比较简单,有时需要复杂一些。例如:特快包裹,冷链包裹

class ExpressPackage extends Package {
    constructor(
        weight: number,
        private unitPrice: number, // 每公⽄的固定费率(快速包裹更⾼)
        private additional: number // 超出10kg以后的附加费
    ) {
        super(weight)
    }

    // 实现抽象⽅法:计算运费
    calculate(): number {
        if(this.weight > 10){
            // 超出10kg的部分,每公⽄多收additional对应的价格
            // 10 * this.unitPrice 表示 10公斤对应的价格
            // (this.weight - 10) * this.additional 表示超过 10公斤对应的价格
            return 10 * this.unitPrice + (this.weight - 10) * this.additional
        }else {
            return this.weight * this.unitPrice;
        }
    }
}

// 创建特快包裹实例
//一个特快包裹重量为13kg,<=10kg 为 8元/kg, >10kg之后 2元/kg
const e1 = new ExpressPackage(13,8,2)
e1.printPackage()

总结

何时使⽤抽象类?

  1. 定义 :为⼀组相关的类定义通⽤的⾏为(⽅法或属性)时。
  2. 提供 :在抽象类中提供某些⽅法或为其提供基础实现,这样派⽣类就可以继承这些实现。
  3. 确保 :强制派⽣类实现⼀些关键⾏为。
  4. 代码和逻辑:当多个类需要共享部分代码时,抽象类可以避免代码重复。