TS 抽象类和多态

2,616 阅读3分钟

「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」。

抽象类

抽象类,听名字似乎是非常难理解的概念,但其实非常简单。

我们知道, JS 是靠原型和原型链来实现面向对象编程的,es6 新增了语法糖 class。

TS 通过 publicprivateprotected 三个修饰符来增强了 JS 中的类。

其实 TS 还对 JS 扩展了一个新概念——抽象类

所谓抽象类,是指只能被继承,但不能被实例化的类,就这么简单。

抽象类有两个特点:

  • 抽象类不允许被实例化
  • 抽象类中的抽象方法必须被子类实现

抽象类用一个 abstract 关键字来定义,我们通过两个例子来感受一下抽象类的两个特点,

抽象类不允许被实例化

abstract class Animal {}

const a = new Animal()

定义一个抽象类 Animal,初始化一个 Animal 的实例,直接报错,

image.png

抽象类中的抽象方法必须被子类实现

abstract class Animal {
    constructor(name:string) {
        this.name = name
    }
    public name: string
    public abstract sayHi():void
}

class Dog extends Animal {
    constructor(name:string) {
        super(name)
    }
}

定义一个 Dog 类,继承自 Animal 类,但是却没有实现 Animal 类上的抽象方法 sayHi,报错,

image.png

正确的用法如下,

abstract class Animal {
    constructor(name:string) {
        this.name = name
    }
    public name: string
    public abstract sayHi():void
}

class Dog extends Animal {
    constructor(name:string) {
        super(name)
    }
    public sayHi() {
        console.log('wang')
    }
}

为什么叫抽象类?

很显然,抽象类是一个广泛和抽象的概念,不是一个实体,就比如上文的例子,动物这个概念是很广泛的,猫、狗、狮子都是动物,但动物却不好是一个实例,实例只能是猫、狗或者狮子。

官方一点的说法是,在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

比如 Animal 类只是具有动物都有的一些属性和方法,但不会具体到包含猫或者狗的属性和方法。

所以抽象类的用法是用来定义一个基类,声明共有属性和方法,拿去被继承。

抽象类的好处是可以抽离出事物的共性,有利于代码的复用。

多态

多态是面向对象的三大基本特征之一。

多态指的是,父类定义一个抽象方法,在多个子类中有不同的实现,运行的时候不同的子类就对应不同的操作,比如,

abstract class Animal {
    constructor(name:string) {
        this.name = name
    }
    public name: string
    public abstract sayHi():void
}

class Dog extends Animal {
    constructor(name:string) {
        super(name)
    }
    public sayHi() {
        console.log('wang')
    }
}

class Cat extends Animal {
    constructor(name:string) {
        super(name)
    }
    public sayHi() {
        console.log('miao')
    }
}

Dog 类和 Cat 类都继承自 Animal 类,Dog 类和 Cat 类都不同的实现了 sayHi 这个方法。

往期

轻松拿下 TS 泛型

TS 中 interface 和 type 究竟有什么区别?

TS 声明文件

TS 高级类型

TS 类型推论

TS 枚举类型

通俗易懂的 TS 基础知识总结