首页/文章/typescript

TS系列篇|类(class)

2024-04-28
14465 分钟
...

"不畏惧,不将就,未来的日子好好努力"——大家好!我是小芝麻😄

类(Class)定义了一件事物的抽象特点,包含它的属性和方法

1、定义类

TypeScript 中,我们也是通过 Class 关键字来定义一个类, 使用 constructor 定义构造函数。

构造函数: constructor

  • 主要用于初始化类的成员变量属性
  • 类的对象创建时自动调用执行
  • 没有返回值
class Animal {
    public name: string;
    constructor(name: string) {
        this.name = name;
    }
    sayHi(): string {
        return `My name is ${this.name}`;
    }
}

2、类的继承

使用 extends 关键字实现继承,子类中使用 super 关键字来调用父类的构造函数和方法。

  • 子类继承父类后子类的实例就拥有了父类中的属性和方法,可以增强代码的可复用性
  • 将子类共用的方法抽象出来放在父类中,自己特殊逻辑放在子类中重写父类的逻辑
  • super 可以调用父类上的方法和属性: (相当于ES5的:在静态方法和构造函数中指向父类; 在普通函数中指向父类的prototype;)
class Animal {
    public name: string;
    constructor(name: string) {
        this.name = name;
    }
    sayHi(): string {
        return `My name is ${this.name}`;
    }
}

class Cat extends Animal {
  constructor(name) {
    super(name); 
    console.log(this.name);
  }
  sayHi(): string { 
    return 'Meow, ' + super.sayHi(); 
  }
}

let c = new Cat('Tom'); 
console.log(c.sayHi()); 

2.1 重写(override) VS 重载(overload)

  • 重写是指子类重写继承自父类的方法
  • 重载是指为同一个函数提供多个类型定义

2.2 继承 VS 多态

  • 继承(inheritance)子类继承父类,子类除了拥有父类的所有特性外,还有一些具体的特性
  • 多态(Polymorphism)由继承而产生了相关的不同的类,对同一个方法可以有不同的行为

3、类的修饰符

TypeScript 中有三类访问修饰符,分别是: publicprivateprotected不写默认为 public

  • public :自己、自己的子类 和其他类都可以访问 (默认值)
  • protected 受保护的 自己和自己的子类能访问, 其他类不能访问
  • private 私有的 只能自己访问,自己的子类不能访问,其他类更不能访问
class Father {
  public name: string
  protected age: number
  private money: number

  constructor(name: string, age: number, money: number) {
    this.name = name
    this.age = age
    this.money = money
  }
  getName(): string {
    return this.name
  }
  setName(name: string): void {
    this.name = name
  }
}
class child extends Father {
  constructor(name: string, age: number, money: number) {
    super(name, age, money)
  }
  desc() {
    console.log(`${this.name}${this.age}${this.money}`)
    
  }
}
let children = new child('金色小芝麻', 18, 1000)
console.log(children.name)
console.log(children.age) 
console.log(children.money) 
  • 当构造函数修饰为 private 时,该类不允许被继承或者实例化:
class Animal {
  public name: string;
  private constructor(name: string) {
    this.name = name;
  }
}
class Cat extends Animal { 
  constructor(name: string) {
    super(name);
  }
}

let a = new Animal('Jack'); 
  • 当构造函数修饰为 protected 时,该类只允许被继承:
class Animal {
  public name: string;
  protected constructor(name: string) {
    this.name = name;
  }
}
class Cat extends Animal {
  constructor(name: string) {
    super(name);
  }
}

let a = new Animal('Jack'); 

4、readonly

readonly 修饰的变量只能在属性声明时或 构造函数 中初始化

class Animal {
  
  public readonly name: string
  constructor(name: string) {
    this.name = name
  }
  changeName(name: string) {
    this.name = name 
  }
}
let a = new Animal('hello')
a.name = '111' 
a.changeName('nihao') 
console.log(a)

readonly 只是在 编译阶段进行代码检查。运行时依然能打印

5、参数属性

在上面的例子中,都是在类的定义的顶部初始化实例属性,在 constructor 里接收参数然后对实例属性进行赋值,参数属性就是为了简化这一过程的

直接在 constructor 构造函数的参数前面加上修饰符或readonly => 等同于在类中定义该属性同时给该属性赋值,使代码更简洁。

class User {
  constructor(public name: string) {}
}
let user = new User('hello')
console.log(user.name) 
user.name = 'nihao'
console.log(user.name) 

6、存取器

  • TypeScript 中,我们可以通过 getter/ setter来改变一个类中属性的读取和赋值行为
class Person {
  name: string
  constructor(name: string) {
    this.name = name
  }
  get getName() { 
    return this.name
  }
  set setName(val: string) { 
    this.name = val.toUpperCase()
  }
}
let p1 = new Person('nihao')
console.log(p1.getName)
p1.setName = 'hello'
console.log(p1.name)

7、静态属性和静态方法static

使用 static 修饰符修饰的方法称为静态方法,它们不需要实例化,而是直接通过类来调用:

class Father {
  public name: string
  constructor(name: string) {
    this.name = name
  }
  public static className: string = 'Father'
  static getClassName(): string {
    return Father.className
  }
  
}
console.log(Father.className)
console.log(Father.getClassName())

8、抽象类和抽象方法abstract

使用 abstract 关键字来定义抽象类和在抽象类内部定义抽象方法。

8.1 抽象类

  • 抽象描述一种抽象的概念,做为其它类的基类使用
  • 无法创建抽象类的实例,抽象类只能被继承
abstract class Animal {
  name!: string
  abstract speak(): void
}

class Cat extends Animal {
  speak() {
    console.log('喵喵喵')
  }
}

let animal = new Animal(); 
let cat = new Cat()
cat.speak() 

8.2 抽象方法

  • 抽象方法不能在抽象类中实现,只能在抽象类的具体子类中实现,而且必须实现
  • 抽象方法只能出现在抽象类中
abstract class Animal {
  name: string
  abstract speak(): void = ()=>{} 
}
class Cat extends Animal {
  speak() { 
    console.log('喵喵喵')
  }
}
  • 子类可以对抽象类进行不同的实现
abstract class Animal {
  abstract speak(): void
}
class Dog extends Animal {
  speak() {
    console.log('汪汪汪')
  }
}

class Cat extends Animal {
  speak() {
    console.log('喵喵喵')
  }
}

8.3 抽象类 VS 接口

  • 不同类之间公有的属性或方法,可以抽象成一个接口(interfaces), 而抽象类是供其他类继承的基类
  • 抽象类本质是一个无法被实例化的类,可以包含成员的实现细节,而接口仅能够用于描述,既不能提供方法的实现细节,也不为属性进行初始化
  • 一个类可以继承一个类或抽象类,但可以实现(implements)多个接口
  • 抽象类也可以实现接口
abstract class Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  abstract speak(): void;
}
interface Flying {
  fly(): void
}
interface age {
  age: number
}
class Dog extends Animal implements Flying, age {
  age: 18
  speak() {
    console.log('汪汪汪')
  }
  fly() {
    console.log('我会飞')
  }
}

| 访问控制修饰符 | private、protected、public | | 只读属性 | readonly | | 静态属性 | static | | 抽象类、抽象方法 | abstract |

参考文献

[1]. TypeScript中文网

[2]. TypeScript 入门教程

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
typescript2025-09-26
彻底讲透as const + keyof typeof
一、为什么要 “as const” 1、默认情况下,TS把字面量推断成”宽类型“ 于是你写 ‘foo’ | ‘bar’ 时, 一旦拼错成 ’fooo‘, TS不会拦你。 2、加上 as const ,TS会把它当成”不可变的精确字面量” 数组、对象同理: 二、keyof typeof: 把值世界映射到类型世界 typeof:能把运行时的值变成类型; keyof:能把对象类型变成联合类型 合起来就是:给我一个对象,我立刻推出它所有建的字面...
学习面试
typescript2025-02-26
TypeScript 中的 interface和 type 类型有什么区别?它们各自有什么用途?
在 TypeScript 中, 和 都可以用于定义类型,但它们有一些细微的差异和特定的应用场景。下面我们详细比较它们的 区别 、 相同点 以及 各自的用途 。 一、相同点 1. 描述对象的结构 : 和 都可以用来描述对象的结构。 2. 都支持可选属性和只读属性 : 3. 都可以扩展 (类似于继承)。不过扩展的方式不同(具体见下文)。 二、区别 | 特性 | interface | type | | | | | | 定义方式 | 使用 关...
学习面试面试官
typescript2024-08-07
TypeScript 中 `type` 和 `interface` 的区别
基本概念: 和 究竟是啥? 就是类型别名,用来给各种类型起个名字。可以是基本类型、对象类型、联合类型、交叉类型、元组等。 则专注于定义对象的结构和行为。它更像是面向对象编程中的蓝图,描述了对象应该拥有哪些属性和方法。 用途和功能:什么时候用 ,什么时候用 ? 的用途和功能 复杂类型组合 : 非常适合定义联合类型、交叉类型和元组。 灵活性高 :可以进行类型变换,比如条件类型和映射类型。 的用途和功能 描述对象结构 : 用来定义对象的形状,...
学习
typescript2024-05-13
破案了,为啥TypeScript5.3编译let、const一直是var
啊!2024才学TypeScript还有价值吗?!学的话,就用最新的上。 1.环境 8.15.4 Version 5.3.3 v20.10.0 2.背景&测试 使用pnpm安装了最新的TypeScript5.3.3,开始学习ts类型。 发现不论是let、const使用tsc编译完都是var。强迫症表示ES2016起不能接受var,尝试各种配置tsconfig.json后无效。 为什么let 经过tsc编译后 let= var 简化此图投...
学习
AI2026-09-01
Deep Agents 01:何为 Agent Harness,以及如何开始
1、本篇任务:完成一份多步骤、带证据的技术调研 普通客服 Agent 的问题短、工具少、输出即时。技术调研或编码任务会持续很久,产生计划、搜索结果、文件和中间结论。Deep Agents 在 LangChain/LangGraph 之上预装规划、虚拟文件系统、上下文压缩和子 Agent,适合这类开放任务。 本课让 Agent 比较两种向量数据库,并交付一份可验证报告。 2、什么时候需要 Deep Agent 满足以下两项以上再考虑:任务...
学习
AI2026-09-01
Deep Agents 02:子 Agent、虚拟文件系统与长期记忆
1、本篇任务:让主管只看结论,让子 Agent 处理细节 技术调研会产生几十次搜索和大量文件。如果全部进入主管上下文,真正的目标会被噪音淹没。本课用两个子 Agent: 收集证据, 检查结论;主管负责计划与最终合成。 2、什么时候委派,什么时候直接调用工具 适合委派:子任务有多步;需要专门提示或工具;会产生大量中间结果;只需返回有限结论。不适合:一步查询;主管需要全部中间上下文;协调成本超过任务本身。 3、配置专门子 Agent Pyt...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录