14_TypeScript 类 --[深入浅出 TypeScript 测试]

devtools/2025/1/16 2:34:36/

TypeScript 的类(Classes)是面向对象编程的核心组成部分,提供了对类的支持,包括继承、访问修饰符、构造函数、静态成员等。通过 TypeScript 类,你可以创建结构良好且类型安全的对象。以下是一些关于 TypeScript 类的关键概念和用法示例。

定义一个简单的类

typescript">/*** Greeter 类用于生成带有特定问候语的欢迎消息。*/
class Greeter {greeting: string;/*** 构造函数,用于创建 Greeter 类的新实例。* * @param message - 传递给构造函数的问候消息,用于设置 greeting 属性。*/constructor(message: string) {this.greeting = message;}/*** 生成欢迎消息。* * @returns 返回包含欢迎消息的字符串。*/greet() {return "Hello, " + this.greeting;}
}// 创建 Greeter 类的一个实例,传入问候消息 "world"
let greeter = new Greeter("world");
// 调用 greeter 实例的 greet 方法,并将欢迎消息输出到控制台
console.log(greeter.greet()); // 输出 "Hello, world"

在这个例子中:

  • greeting 是一个类的属性。
  • constructor 是构造函数,用于初始化新创建的对象。
  • greet 是一个方法,返回一个问候信息。

访问修饰符

TypeScript 提供了三种访问修饰符来控制类成员的可见性:

  • public:默认值,成员可以在任何地方被访问。
  • private:成员只能在定义它们的类内部访问。
  • protected:成员可以在其自身类以及派生类中访问。

访问修饰符是 TypeScript 类中用来控制类成员(属性和方法)可见性和可访问性的关键字。TypeScript 提供了三种访问修饰符:publicprivateprotected。下面通过一个具体的例子来展示这些访问修饰符的使用。

示例:使用访问修饰符

typescript">class Employee {// 默认为 public,可以在任何地方访问public department: string;// private 成员只能在定义它的类内部访问private salary: number;// protected 成员可以在其自身类以及派生类中访问protected id: number;constructor(department: string, salary: number, id: number) {this.department = department;this.salary = salary;this.id = id;}// 公共方法,可以公开访问public getDetails(): void {console.log(`Employee in ${this.department}, ID: ${this.id}`);this.printSalary(); // 私有方法可以在类内调用}// 私有方法,只能在类内部调用private printSalary(): void {console.log(`Salary: ${this.salary}`);}
}// 创建 Employee 类的实例
let emp = new Employee("Engineering", 70000, 12345);// 可以访问公共成员
console.log(emp.department); // 输出 "Engineering"// 不能直接访问私有成员或方法
// console.log(emp.salary); // Error: Property 'salary' is private and only accessible within class 'Employee'.
// emp.printSalary(); // Error: Method 'printSalary' is private and only accessible within class 'Employee'.// 可以访问保护成员,但在外部无法直接访问
// console.log(emp.id); // Error: Property 'id' is protected and only accessible within class 'Employee' and its subclasses.

在这个例子中:

  • department 是一个 public 属性,默认情况下所有类成员都是 public 的,这意味着它们可以在任何地方被访问。
  • salary 是一个 private 属性,它只能在 Employee 类的内部访问。尝试从外部访问会导致编译错误。
  • id 是一个 protected 属性,它不仅可以在 Employee 类内部访问,也可以在其派生类中访问,但在类外部仍然不可见。
  • getDetails 是一个 public 方法,因此可以从外部调用。
  • printSalary 是一个 private 方法,只能在 Employee 类的内部调用。
输出结果:
Engineering
Employee in Engineering, ID: 12345
Salary: 70000

扩展:继承与保护成员

为了进一步说明 protected 访问修饰符的作用,我们可以创建一个继承自 Employee 的子类,并查看如何访问 protected 成员。

typescript">class Manager extends Employee {constructor(department: string, salary: number, id: number, public reports: number) {super(department, salary, id);}// 子类可以访问父类中的 protected 成员showId(): void {console.log(`Manager ID: ${this.id}`); // OK, because 'id' is protected}
}let manager = new Manager("Management", 90000, 67890, 5);manager.getDetails(); // 调用继承的方法
manager.showId();     // 调用子类中的方法,可以访问 protected 成员

在这个扩展的例子中:

  • Manager 类继承自 Employee,并且能够访问 protectedid 属性。
  • showId 方法展示了如何在子类中合法地访问 protected 成员。

通过这个例子,你可以看到不同访问修饰符对类成员访问权限的影响,这有助于构建更加模块化和安全的代码结构。合理使用访问修饰符可以确保你的类设计既灵活又安全。

继承

子类可以继承父类的属性和方法,并可以重写或扩展这些成员。

typescript">/*** 定义一个Person类,用于表示一个人的基本信息*/
class Person {protected name: string;/*** 构造函数,初始化人的姓名* @param name 人的姓名*/constructor(name: string) {this.name = name;}/*** 说你好的方法* @returns 返回一个打招呼的字符串*/sayHello() {return `Hello, my name is ${this.name}`;}
}/*** 定义一个Employee类,继承自Person类,用于表示一个员工的信息*/
class Employee extends Person {private department: string;/*** 构造函数,初始化员工的姓名和部门* @param name 员工的姓名* @param department 员工所属的部门*/constructor(name: string, department: string) {super(name); // 调用父类的构造函数this.department = department;}/*** 获取电梯演讲的内容* @returns 返回一个包含打招呼和工作部门信息的字符串*/getElevatorPitch() {return `${this.sayHello()} and I work in ${this.department}.`;}
}// 创建一个Employee实例
let howard = new Employee("Howard", "Sales");
// 输出电梯演讲的内容
console.log(howard.getElevatorPitch()); // 输出 "Hello, my name is Howard and I work in Sales."

静态成员

你可以使用 static 关键字来定义属于类而不是实例的属性和方法。

typescript">// 定义一个Grid类,用于在二维平面上进行距离计算
class Grid {// 静态属性origin代表坐标原点static origin = { x: 0, y: 0 };/*** 计算给定点到原点的距离* @param point 一个包含x和y坐标的对象,表示要计算距离的点* @returns 返回计算出的距离,根据实例化的scale比例进行调整*/calculateDistanceFromOrigin(point: { x: number; y: number }) {let xDist = point.x - Grid.origin.x;let yDist = point.y - Grid.origin.y;return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;}// 构造函数,接受一个scale参数,用于距离计算时的比例调整constructor(public scale: number) {}
}// 创建一个比例为1的Grid实例
let grid1 = new Grid(1.0);  // 1x scale
// 创建一个比例为5的Grid实例
let grid2 = new Grid(5.0);  // 5x scale// 使用grid1实例计算点(10, 10)到原点的距离并打印
console.log(grid1.calculateDistanceFromOrigin({ x: 10, y: 10 })); // 输出 14.142135623730951
// 打印Grid类的静态属性origin的x坐标
console.log(Grid.origin.x); // 输出 0

抽象类

抽象类不能直接实例化,通常作为基类来定义一组接口或实现某些通用功能。

typescript">/*** 抽象类Department用于定义一个部门的基本属性和方法*/
abstract class Department {/*** 构造函数,初始化部门名称* @param name 部门的名称*/constructor(public name: string) {}/*** 打印部门名称的方法*/printName(): void {console.log('Department name: ' + this.name);}/*** 抽象方法,用于打印会议信息* 必须在派生类中实现*/abstract printMeeting(): void;
}/*** AccountingDepartment类继承自Department类* 用于定义会计部门的具体行为*/
class AccountingDepartment extends Department {/*** 实现了抽象方法printMeeting,具体打印会计部门的会议信息*/printMeeting(): void {console.log('The Accounting Department meets each Monday at 10am.');}/*** 生成会计报告的方法*/generateReports(): void {console.log('Generating accounting reports...');}
}// 声明一个Department类型的变量
let department: Department;// department = new Department(); // 错误: 抽象类不能实例化
// 实例化AccountingDepartment对象
department = new AccountingDepartment("Accounting");// 调用部门的打印名称方法
department.printName();
// 调用部门的打印会议信息方法
department.printMeeting();

获取器与设置器(Getters & Setters)

TypeScript 支持 JavaScript 的 getter 和 setter 方法,允许你更细粒度地控制属性的读取和赋值操作。

typescript">/*** 定义一个员工类*/
class Employee {// 员工全名的私有属性private _fullName: string;/*** 获取员工全名* @returns {string} 员工的全名*/get fullName(): string {return this._fullName;}/*** 设置员工全名* @param {string} newName 新的全名* @throws {Error} 如果名字长度小于等于3,则抛出错误*/set fullName(newName: string) {if (newName && newName.length > 3) {this._fullName = newName;} else {throw new Error("Invalid name");}}
}// 创建员工实例
let employee = new Employee();
// 设置员工全名,这里是一个有效的名字
employee.fullName = "Bob Smith";
// 输出员工全名
console.log(employee.fullName); // 输出 "Bob Smith"// 尝试设置一个无效的名字,这会抛出错误
// employee.fullName = "John"; // 这会抛出错误,因为名字长度不足

总结

  • 定义类:使用 class 关键字。
  • 访问修饰符publicprivateprotected 控制成员的可见性。
  • 继承:使用 extends 关键字从现有类派生新类。
  • 静态成员:使用 static 关键字定义不属于实例的成员。
  • 抽象类:定义不能直接实例化的基类。
  • 获取器与设置器:提供对属性的受控访问。

通过理解和应用这些特性,你可以利用 TypeScript 的强大功能构建复杂且类型安全的应用程序。类是组织代码的重要工具,帮助你创建可复用、易于维护和扩展的组件。


http://www.ppmy.cn/devtools/150817.html

相关文章

分布式缓存redis

分布式缓存redis 1 redis单机(单节点)部署缺点 (1)数据丢失问题:redis是内存存储,服务重启可能会丢失数据 (2)并发能力问题:redis单节点(单机)部…

Python PyQt 子类中回调主类的函数,回调

有时我们需要在子类计算完成后,回调主类的方法显示数据; 这时我们可以用以下方式,python 确实方便; 1. 子类: from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget# 子类 c…

机器学习 - 如何理解几何学中的超平面 ?

线性回归公式 ywTxb 是数据建模中的基础: 数学上,它是一个线性函数。几何上,它是一个超平面。 那么如何理解超平面这个概念呢? 超平面(hyperplane)是几何学中的一个基本概念,尤其在高维空间和…

【C语言】字符串函数详解

文章目录 Ⅰ. strcpy -- 字符串拷贝1、函数介绍2、模拟实现 Ⅱ. strcat -- 字符串追加1、函数介绍2、模拟实现 Ⅲ. strcmp -- 字符串比较1、函数介绍2、模拟实现 Ⅳ. strncpy、strncat、strncmp -- 可限制操作长度Ⅴ. strlen -- 求字符串长度1、函数介绍2、模拟实现&#xff08…

CSS语言的网络编程

CSS语言的网络编程 引言 CSS(Cascading Style Sheets,层叠样式表)是一种用于描述HTML或XML文档外观样式的样式表语言。虽然CSS本身并不是一种编程语言,但它在网页设计和开发中发挥着至关重要的作用。随着互联网的发展&#xff0…

我在2025年自学网络安全(黑客)

当我们谈论网络安全时,我们正在讨论的是保护我们的在线空间,这是我们所有人的共享责任。网络安全涉及保护我们的信息,防止被未经授权的人访问、披露、破坏或修改。 一、网络安全的基本概念 网络安全是一种保护:它涉及保护我们的…

GitLab本地服务器配置ssh和克隆项目

1. 本地安装好git git链接:https://git-scm.com/downloads/win 无脑点击下一步安装即可,打开Git Bash命令终端如下: 2. 配置本地用户名和邮箱 git config --global user.name "你的名字" git config --global user.email "你的邮箱&quo…

Oracle分析工具-Logminer手动指定归档文件

1.概述 Logminer是自Oracle8i以后推出的分析工具,它可以读取 Oracle 数据库的归档日志和在线日志,并将其转换为易于分析的格式。logminer分析工具由一组PL/SQL包和一些动态视图组成,Oracle提供了continuous_mine参数来进行日志的持续挖掘&am…