「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」。
抽象类
抽象类,听名字似乎是非常难理解的概念,但其实非常简单。
我们知道, JS 是靠原型和原型链来实现面向对象编程的,es6 新增了语法糖 class。
TS 通过 public、private、protected 三个修饰符来增强了 JS 中的类。
其实 TS 还对 JS 扩展了一个新概念——抽象类。
所谓抽象类,是指只能被继承,但不能被实例化的类,就这么简单。
抽象类有两个特点:
- 抽象类不允许被实例化
- 抽象类中的抽象方法必须被子类实现
抽象类用一个 abstract 关键字来定义,我们通过两个例子来感受一下抽象类的两个特点,
抽象类不允许被实例化
abstract class Animal {}
const a = new Animal()
定义一个抽象类 Animal,初始化一个 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)
}
}
定义一个 Dog 类,继承自 Animal 类,但是却没有实现 Animal 类上的抽象方法 sayHi,报错,
正确的用法如下,
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 这个方法。
往期