含义
抽象类是干啥的,为什么要抽象类?
抽象(abstract)这个词本身理解起来就是客观不存在的,是一个概念上,一个泛词。例如:飞机,鸟,坦克等
飞机大战也许都玩过,里面有好多飞机,有敌方的飞机,玩家飞机等。那么根据类的划分,我们可以划分敌方飞机类,玩家飞机类,但是我们从继承的角度仔细想一想,是不是有一些公共的部分,例如,飞机的名字,飞机的生命值,飞机的速度,攻击等一系列公共的属性和方法,就可以得出下面的类图
我们也可以写出现下面的代码:
class Plane{ name:string = ''; life:string = ''; attack(){ console.log(`{this.name}飞机正在攻击`) } } class PlayerPlane extends Plane{ name:string = '玩家1'; life:string = '100'; // ... attack(){ console.log(`{this.name}飞机正在攻击`); // 飞机相同的逻辑1 // 飞机相同的逻辑2 // 飞机的不同逻辑 } } class EnemyPlane extends Plane{ name:string = '小罗罗1'; life:string = '10'; // ... attack(){ console.log(`{this.name}飞机正在攻击`) // 飞机相同的逻辑1 // 飞机相同的逻辑2 // 飞机的不同逻辑 } }
写完上面代码,大家有没有发现一些问题
1.父类的属性列表中的属性必须赋值,不赋值ts 的严格检查会报错,我们从逻辑上可以知道,父类的名字我咋知道是啥啊!
2.两个字类可以写很多重复的代码
有时,某个类只表示一个抽象概念,主要用于提取子类共有的成员,而不能直接创建它的对象。该类可以作为抽象类。
语法: abstract class xxx {}
表示该类是一个抽象类,也可以抽象属性,抽象方法,但是不可以创建一个抽象类的对象
改写上面的代码:
实现抽象属性
方式一:
直接重写改属性,并且在属性列表中赋上默认的值就好
方式二:
通过构造函数来实现赋值:
方式三:
通过get函数来进行属性赋值:
但是get函数的缺陷,如果只设置get,没有set函数,改属性是一个只读的哦
abstract class Plane { abstract name: string; abstract life: string; attack() { console.log(`{this.name}飞机正在攻击`) // 飞机相同的逻辑1 // 飞机相同的逻辑2 this.otherFunction(); } // 飞机的不同逻辑 abstract otherFunction() } class PlayerPlane extends Plane { name:string = '玩家1'; life:string = '100' otherFunction(){ // ...个性化 } } class EnemyPlane extends Plane { name:string = '小罗罗1'; life:string = '10' otherFunction(){ // ...个性化 } }
模板模式:有些方法,所有的子类实现的流程完全一致,只是流程中的某个步骤的具体实现不一致,可以将该方法提取到父类,在父类中完成整个流程的实现(上面代码中的attack()),遇到实现不一致的方法时(把该方法做成抽象方法,字类必须去实现),将该方法做成抽象方法。这种设计模式是大名鼎鼎的 模板模式