Class 类的基础语法
创建类
class
关键字加"类名"即可
ts
class Player {
}
定义属性
属性一般写在类里面的顶部
ts
class Player {
// 定义属性
name: string;
health: number;
damage: number;
}
constructor 方法
constructor 方法用于给实例的属性赋值,并设定默认值
constructor 接收一个参数 props,类型为 PlayerProps
,逐个从 props 中取出各属性,并用 ??
(||
的升级版,保留了''
、0
、false
)后面加默认值
注意 this 的指向:class 类里的 this 指向用此类 new 生成的实例
所以 this.name = props.name ?? 'Unknown'
就是在给实例的属性赋初值的过程
ts
interface PlayerProps {
name?: string; // 名称
health?: number; // 血量
damage?: number; // 伤害值
}
class Player {
// 定义属性
name: string;
health: number;
damage: number;
// 为属性赋值(并规定好默认值)
constructor(props: PlayerProps) {
this.name = props.name ?? 'Unknown';
this.health = props.health ?? 0;
this.damage = props.damage ?? 0;
}
}
定义方法
ts
interface PlayerProps {
name?: string; // 名称
health?: number; // 血量
damage?: number; // 伤害值
}
class Player {
// 定义属性
name: string;
health: number;
damage: number;
// 为属性赋值(并规定好默认值)
constructor(props: PlayerProps) {
this.name = props.name ?? 'Unknown';
this.health = props.health ?? 0;
this.damage = props.damage ?? 0;
}
// 定义方法
move(direction: 'left' | 'right') {
console.log(`${this.name}向${direction}移动`);
}
recover(bloodVolume: number) {
console.log(`${this.name}恢复血量:+${bloodVolume}`);
this.health += bloodVolume;
}
}
自此,一个 Player 类已创建完成
创建实例并测试
ts
const player1 = new Player({
name: 'PlayerA',
health: 100,
damage: 20
);
console.log(player1.name); // PlayerA
console.log(player1.health); // 100
console.log(player1.damage); // 20
player1.move('left'); // PlayerA向left移动
player1.recover(10); // PlayerA恢复血量:+10
Class 类的继承
想要实现这样的继承关系:
- 玩家
Player
是基类,战士Warrior
和射手Shooter
是子类,都继承自Player
基类 - 基类
Player
通用属性:名称、血量、伤害值;通用方法:移动、恢复生命 - 子类
Warrior
独有属性:防御伤害值;独有方法:开启盾牌防御 - 子类
Shooter
独有属性:射程;独有方法:射击
定义基类和子类的属性类型
extends
表示"继承自"WarriorProps
既包含PlayerProps
的所有属性,又包含自己的属性defense
ts
interface PlayerProps {
name?: string; // 玩家通用属性:名称
health?: number; // 玩家通用属性:血量
damage?: number; // 玩家通用属性:伤害值
}
interface WarriorProps extends PlayerProps {
defense?: number; // 战士独有属性:防御伤害值
}
interface ShooterProps extends PlayerProps {
shootRange?: number; // 射手独有属性:射程
}
子类继承自基类
extends
表示"继承自"super
表示"父类的构造函数"
ts
class Warrior extends Player {
defense?: number; // 战士独有的属性:防御伤害值
constructor(props: WarriorProps) {
super(props); // 调用父类的构造函数,传递参数
this.defense = props.defense ?? 0; // 初始化 Warrior 类独有的属性
}
defend() {
console.log(`${this.name}独有的技能:开启盾牌防御`);
}
}
class Shooter extends Player {
shootRange?: number; // 射手独有的属性:射程
constructor(props: ShooterProps) {
super(props); // 调用父类的构造函数,传递参数
this.shootRange = props.shootRange ?? 0; // 初始化 Shooter 类独有的属性
}
shoot() {
console.log(`${this.name}独有的技能:射击`);
}
}
自此,子类 Warrior、Shooter 已创建完成
创建子类实例并测试
ts
const warrior1 = new Warrior({
name: 'WarriorA',
health: 100,
damage: 30,
defense: 15,
});
// 实例 warrior1 使用了 Player 类的通用属性及方法
console.log(`${warrior1.name}的血量:${warrior1.health},伤害值:${warrior1.damage}`);
warrior1.move('left');
warrior1.recover(10);
// 实例 warrior1 使用了 Warrior 类的独有属性及方法
console.log(`${warrior1.name}独有的属性:防御伤害值为${warrior1.defense}`);
warrior1.defend();
// warrior1.shoot(); // 实例 warrior1 无法调用 Shooter 类独有的方法
console.log('----------------');
const shooter1 = new Shooter({
name: 'ShooterA',
health: 100,
damage: 50,
shootRange: 10,
});
// 实例 shooter1 使用了 Player 类的通用属性及方法
console.log(`${shooter1.name}的血量:${shooter1.health},伤害值:${shooter1.damage}`);
shooter1.move('right');
shooter1.recover(10);
// 实例 shooter1 使用了 Shooter 类的独有属性及方法
console.log(`${shooter1.name}独有的属性:射程为${shooter1.shootRange}`);
shooter1.shoot();
// shooter1.defend(); // 实例 shooter1 无法调用 Warrior 类独有的方法
console.log('----------------');
const warrior2 = new Warrior({});
console.log(`${warrior2.name}的血量:${warrior2.health},伤害值:${warrior2.damage}`);
const shooter2 = new Shooter({
name: 'ShooterB',
});
console.log(`${shooter2.name}的血量:${shooter2.health},伤害值:${shooter2.damage}`);
输出结果:
顺便提一嘴,vscode 如何运行 ts 文件:
- npm 安装
typescript
和ts-node
bash
npm install -g typescript
npm install -g ts-node
- 安装 VScode 插件:
Code Runner
- 保存 ts 文件后点击 VScode 右上角的 Run Code 按钮