9、深入理解TS类(进阶篇)

194 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情

想深入的理解类和接口, 就离不开面向对象的编程思想。

TS 中使用面向对象的优势

js 中由于没有类型检查, 在使用面向对象的开发, 会产生大量的属性、函数, 由于没有类型检查去调用这些属性、函数, 我们需要清除的记得每一个属性、函数时干嘛的, 从而导致复杂度剧增, 为了减少这种复杂度就必须使用严格的类型检查来避免错误, TS 就能完美的解决, 这也是 TS 适合使用面向对象开发的优势。

类的继承

继承的作用

继承可以描述类与类之间的关系

如果AB都是类, 并且可以描述为AB, 则AB形成继承关系:

  • B是父类, A是子类
  • B派生A, A继承自B
  • BA的基类, AB的派生类

如果A继承自B, 则A中自动拥有B中的所有成员

举个栗子: 我是人, 我继承自人, 所以我拥有人的所有特性。

继承的写法

假如我在使用面向对象的方式在写一个飞机大战的游戏, 我可以写至少 3 个类:

  • 飞机类
  • 敌方飞机类 继承 飞机类
  • 我方飞机类 继承 飞机类

举个栗子:

//飞机类 --- 敌方飞机和我方飞机共同的基类
class Plane {
    x: number = 0 //横坐标
    y: number = 0 //纵坐标
    hp: number = 100 //血量
    speed: number = 10 //速度
}

//敌机
class Enemy extends Plane {
    //这里可以定义敌机的其他属性
}

//我方飞机
class OurPlanes extends Plane {
    //这里可以定义我方飞机的其他属性
}

可以通过 extends关键字完成继承。

属性的重写

//我方飞机
class OurPlanes extends Plane {
    x: number = 100
    y: number = 100
}

OurPlanes 继承 Plane 所以 OurPlanes 具有 x、y 属性并且可以覆盖, 但属性的类型不能更改(逻辑上说不通)。

单根性和传递性

单根性: 每个类最多只能拥有一个父类。

传递性: 如果 AB 的父类 BC 的父类,则 A 也是 C 的父类。

抽象类

抽象类表示一种抽象的概念没有具体的事物可以表示出来, ts 中的抽象类表示:如果一个类是抽象类那么这个类就不能使用 new 关键字创建。

举个栗子

假如我在写五子棋游戏:游戏中有 白棋黑旗 它们就可以集成至一个公共的类 棋子,我可以在代码中 new 白棋 new 黑棋,但是决不能 new 棋子 一但创建就是逻辑上出现了 bug, 因为在五子棋游戏中只能有 黑白棋子, 这里的 棋子 是一个抽象类, 为了避免不小心创建抽象类应该给 抽象类加上 abstract 关键字


//棋子类
abstract class Chess {
    
}
//白棋
class white extends Chess {
   
}
//黑旗
class black extends Chess {
   
}

const c  = new Chess(); //error 无法创建抽象类的实例
const c  = new white(); //success

抽象成员

抽象成员只能出现在抽象类中

在父类中, 可以知道有些成员是必须存在的, 但是不知道该成员的值或实现是什么, 因此需要有一个强约束, 让继承该类的子类必须实现该成员。

抽象属性

每一个棋子必须有一个颜色属性, 但是在 棋子类 中不知道在值得具体值, 所以在 棋子类color是一个抽象属性

//棋子类
abstract class Chess {
    abstract color:string; //抽象成员
}

//白棋
class white extends Chess {
   color: string = 'white'; //必须实现该属性
}

//黑旗
class black extends Chess {
   color: string = 'black';
}

抽象方法

有一个move移动方法, 白棋黑旗的移动方式可能不同, 所以 棋子类 无法实现, 需要子类自己完成。

//棋子类
abstract class Chess {
    //是否移动成功
    abstract move(): boolean;
}
//白棋
class white extends Chess {
    move(): boolean {
        console.log("白棋移动成功");
        return true;
    }
}
//黑旗
class black extends Chess {
    move(): boolean {
        console.log("黑棋移动成功");
        return true;
    }
}

总结

当类和面向对象的编程思想结合时你会发现它们多么美妙。