TypeScript类:面向对象编程的基石

news2025/3/13 3:30:30

一、从现实世界到代码世界

想象你要建造一栋房子,首先需要一张设计蓝图——它定义了房屋的结构(几个房间)、功能(卧室/厨房)和特性(材料/颜色)。在TypeScript中,class就是这个设计蓝图,而根据蓝图建造出来的具体房屋就是对象实例

二、类的核心组成

1. 基础类结构

class Smartphone {
    // 属性声明
    brand: string;
    storage: number;
    
    // 构造函数
    constructor(brand: string, storage: number) {
        this.brand = brand;
        this.storage = storage;
    }

    // 方法
    checkStorage(): string {
        return `${this.storage}GB remaining`;
    }
}

// 创建实例
const myPhone = new Smartphone("Pixel", 128);
console.log(myPhone.checkStorage()); // 输出:128GB remaining

2. 类成员修饰符

TypeScript通过访问修饰符增强了类的封装性:

修饰符访问范围示例代码
public所有地方(默认)public id: number
private仅类内部private secret: string
protected类及其子类protected key: string
readonly只读属性readonly serial: string
class BankAccount {
    private _balance: number; // 真正存储值的私有字段
    readonly accountNumber: string;

    constructor(initial: number, num: string) {
        this._balance = initial;
        this.accountNumber = num;
    }

    public get balance(): number { // 访问器属性
        return this._balance;
    }
}

const account = new BankAccount(1000, "622588");
console.log(account.balance);  // ✔ 允许访问
// account._balance = 5000;    // ❌ 编译错误

3. 继承与多态

// 基类
class Animal {
    constructor(public name: string) {}

    move(distance: number = 0) {
        console.log(`${this.name} moved ${distance}m`);
    }
}

// 派生类
class Snake extends Animal {
    constructor(name: string) {
        super(name); // 必须调用父类构造函数
    }

    // 方法重写
    override move(distance = 5) {
        console.log("Slithering...");
        super.move(distance); // 调用父类方法
    }
}

const sam = new Snake("Sammy");
sam.move(); // 输出:Slithering... Sammy moved 5m

三、高级类特性

1. 抽象类

abstract class Shape {
    abstract getArea(): number; // 抽象方法

    printArea() {
        console.log(`Area: ${this.getArea()}`);
    }
}

class Circle extends Shape {
    constructor(public radius: number) {
        super();
    }

    override getArea(): number {
        return Math.PI * this.radius ** 2;
    }
}

// const shape = new Shape(); // ❌ 错误:不能实例化抽象类
const circle = new Circle(5);
circle.printArea(); // 输出:Area: 78.5398...

2. 静态成员

class URLHelper {
    static BASE_DOMAIN = "https://api.example.com";

    static buildUserEndpoint(userId: number): string {
        return `${this.BASE_DOMAIN}/users/${userId}`;
    }
}

console.log(URLHelper.buildUserEndpoint(123)); 
// 输出:https://api.example.com/users/123

3. 方法重载

class Calculator {
    // 方法重载签名
    add(a: number, b: number): number;
    add(a: string, b: string): string;
    
    // 实现签名
    add(a: any, b: any): any {
        if (typeof a === "string") {
            return a + b;
        }
        return a + b;
    }
}

const calc = new Calculator();
console.log(calc.add(1, 2));    // 3
console.log(calc.add("1", "2"));// "12"

四、类与接口的协作

// 定义接口
interface Loggable {
    log(): void;
}

// 实现接口
class FileLogger implements Loggable {
    log() {
        console.log("Writing to file...");
    }
}

// 多接口实现
class DatabaseLogger implements Loggable {
    log() {
        console.log("Saving to database...");
    }
    connect() {
        console.log("Connecting DB...");
    }
}

五、最佳实践指南

  1. 单一职责原则
    每个类应该只有一个引起变化的原因

  2. 组合优于继承
    优先使用对象组合而不是类继承:

class Engine { /* ... */ }
class Car {
    constructor(private engine: Engine) {}
}
  1. 明确访问控制
    除非必要,否则属性都应设为private

  2. 避免深度继承
    继承层级建议不超过3层

  3. 合理使用抽象
    通过抽象类定义通用行为

六、常见误区提醒

❌ 误区1:认为private是绝对安全的
实际上编译后的JavaScript中私有属性仍然可见

❌ 误区2:过度使用继承
导致类之间高度耦合,增加维护难度

❌ 误区3:忽略super()调用
在派生类构造函数中忘记调用super()会导致错误

七、类与JavaScript的差异

特性TypeScriptJavaScript ES6
访问修饰符支持public/private/protected无原生支持
抽象类支持不支持
接口实现显式implements语法
属性声明类顶部显式声明在构造函数中初始化

结语

TypeScript类不仅保留了JavaScript的灵活性,还通过类型系统和面向对象特性,帮助开发者构建更健壮的应用程序。掌握类的使用是成为TypeScript开发者的重要一步,但记住:真正的面向对象设计不在于使用多少高级语法,而在于如何用合理的抽象解决实际问题。

如果对你有帮助,请帮忙点个赞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2314057.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++之序列容器(vector,list,dueqe)

1.大体对比 在软件开发的漫长历程中,数据结构与算法始终占据着核心地位,犹如大厦的基石,稳固支撑着整个程序的运行。在众多编程语言中,数据的存储与管理方式各有千秋,而 C 凭借其丰富且强大的工具集脱颖而出&#xff…

安卓Android与iOS设备管理对比:企业选择指南

目录 一、管理方式差异 Android Enterprise方案包含三种典型模式: Apple MDM方案主要提供两种模式: 二、安全防护能力 Android系统特点: 三、应用管理方案 四、设备选择建议 五、典型场景推荐 需求场景 推荐方案 六、决策建议要点…

版本控制器Git(1)

文章目录 前言一、初识Git问题引入解决方案注意事项 二、Git安装三、Git配置与基本操作Git创建Git配置用户名称和地址认识工作区、暂存区、版本库添加文件到仓库添加文件到暂存区提交暂存区内容到本地仓库 查看提交历史 四、Git 暂存区、HEAD、对象库及文件Git内部结构概览查看…

推理模型对SQL理解能力的评测:DeepSeek r1、GPT-4o、Kimi k1.5和Claude 3.7 Sonnet

引言 随着大型语言模型(LLMs)在技术领域的应用日益广泛,评估这些模型在特定技术任务上的能力变得越来越重要。本研究聚焦于四款领先的推理模型——DeepSeek r1、GPT-4o、Kimi k1.5和Claude 3.7 Sonnet在SQL理解与分析方面的能力,…

[动手学习深度学习]12.权重衰退

1.介绍 权重衰退是常见的处理过拟合的方法 控制模型容量方法 把模型控制的比较小,即里面参数比较少使参数选择范围小 约束就是正则项 每个特征的权重都大会导致模型复杂,从而导致过拟合。 控制权重矩阵范数可以使得减少一些特征的权重,甚至…

JavaEE_多线程(二)

目录 1. 线程的状态2. 线程安全2.1 线程不安全问题的原因 3. 线程安全中的部分概念3.1 原子性3.2 可见性3.3 指令重排序 4. 解决线程安全问题4.1 synchronized关键字4.1.1 可重入4.1.2 synchronized使用 4.2 volatile关键字4.2.1 volatile使用 5. wait和notify5.1 wait()方法5.…

【unity小技巧】分享vscode如何进行unity开发,且如何开启unity断点调试模式,并进行unity断点调试(2025年最新的方法,实测有效)

文章目录 前言一、前置条件1、已安装Visual Studio Code,并且unity首选项>外部工具>外部脚本编辑器选择为Visual Studio Code [版本号],2、在Visual Studio Code扩展中搜索Unity,并安装3、同时注意这个插件下面的描述,需要根…

【Hadoop】详解HDFS

Hadoop 分布式文件系统(HDFS)被设计成适合运行在通用硬件上的分布式文件系统,它是一个高度容错性的系统,适合部署在廉价的机器上,能够提供高吞吐量的数据访问,非常适合大规模数据集上的应用。为了做到可靠性,HDFS创建了…

Spring(4)——响应相关

一、返回静态页面 1.1**RestController和Controller** 想返回如下页面: 如果我们依旧使用原来的**RestController** 可以看到的是仅仅返回了字符串。 此时将**RestController改为Controller** 可以看到这次返回的是html页面。 那么**RestController和Controller…

axure11安装教程包含下载、安装、汉化、授权(附安装包)图文详细教程

文章目录 前言一、axure11安装包下载二、axure11安装教程1.启动安装程序2.安装向导界面3.安装协议协议页面2.选择安装位置3.开始安装4.完成安装 三、axure11汉化教程1.axure11汉化包2.axure11汉化设置 四、axure11授权教程1.打开axure112.设置使用方式3.输入许可证号4.axure11安…

Redis-缓存穿透击穿雪崩

1. 穿透问题 缓存穿透问题就是查询不存在的数据。在缓存穿透中,先查缓存,缓存没有数据,就会请求到数据库上,导致数据库压力剧增。 解决方法: 给不存在的key加上空值,防止每次都会请求到数据库。布隆过滤器…

Windows server网络安全

摘要 安全策略 IP安全策略,简单的来说就是可以通过做相应的策略来达到放行、阻止相关的端口;放行、阻止相关的IP,如何做安全策略,小编为大家详细的写了相关的步骤: 解说步骤: 阻止所有: 打…

Python从入门到精通1:FastAPI

引言 在现代 Web 开发中,API 是前后端分离架构的核心。FastAPI 凭借其高性能、简洁的语法和自动文档生成功能,成为 Python 开发者的首选框架。本文将从零开始,详细讲解 FastAPI 的核心概念、安装配置、路由设计、请求处理以及实际应用案例&a…

Leetcode做题记录----2

1、两数之和 思路: 1、不能使用相同元素,可以想到哈希表,,C#中可以通过字典建立当前值和下标的关系 2、显然,依次判断数组中的每个数即可 3、定义other target - num[ i ] 这个other就是我们用于在字典中进行寻找…

批量合并 Word 文档,支持合并成一个 Word,也支持按文件夹合并

我们经常会碰到需要将多个 Word 文档批量合并成一个 Word 文档的场景,比如需要合并后打印、合并后方便整理存档等等。如果是人工的操作,会非常的麻烦。因此我们通常会借助一些批量处理脚本或者寻找批量处理的工具来帮我们实现批量合并 Word 文档的操作。…

项目实操分享:一个基于 Flask 的音乐生成系统,能够根据用户指定的参数自动生成 MIDI 音乐并转换为音频文件

在线体验音乐创作:AI Music Creator - AI Music Creator 体验者账号密码admin/admin123 系统架构 1.1 核心组件 MusicGenerator 类 负责音乐生成的核心逻辑 包含 MIDI 生成和音频转换功能 管理音乐参数和音轨生成 FluidSynth 集成 用于 MIDI 到音频的转换 …

神经网络为什么要用 ReLU 增加非线性?

在神经网络中使用 ReLU(Rectified Linear Unit) 作为激活函数的主要目的是引入非线性,这是神经网络能够学习复杂模式和解决非线性问题的关键。 1. 为什么需要非线性? 1.1 线性模型的局限性 如果神经网络只使用线性激活函数&…

动态规划详解(二):从暴力递归到动态规划的完整优化之路

目录 一、什么是动态规划?—— 从人类直觉到算法思维 二、暴力递归:最直观的问题分解方式 1. 示例:斐波那契数列 2. 递归树分析(以n5为例) 3. 问题暴露 三、第一次优化:记忆化搜索(Memoiza…

ubuntu下在pycharm中配置已有的虚拟环境

作者使用的ubuntu系统位于PC机上的虚拟机。系统版本为: 在配置pycharm解释器之前你需要先创建虚拟环境以及安装pycharm。 作者创建的虚拟环境位于/home/topeet/miniconda3/envs/airproject/,如下图所示: 作者安装的pycharm版本为2023社区…

爬虫中一些有用的用法

文本和标签在一个级别下 如果文本和a标签在一个级别下 比如: # 获取a标签后的第一个文本节点text_node a.xpath(following-sibling::text()[1])[0].strip() 将xpath的html代码转换成字符串 etree.tostring(root, pretty_printTrue, encoding"utf-8")…