TypeScript与面向对象编程

引言

TypeScript简介

TypeScript是JavaScript的一个超集,由微软开发,它在JavaScript的基础上添加了类型系统和对ES6+的新特性的支持。TypeScript最终会被编译成纯JavaScript代码,以便在任何支持JavaScript的环境中运行。

面向对象编程(OOP)概念

面向对象编程是一种编程范式,它使用“对象”来设计软件。对象可以包含数据(通常称为属性)和代码(通常称为方法)。

面向对象编程基础

面向对象编程(OOP)是一种编程范式,它使用“对象”来设计软件。对象是类的实例,包含了数据和操作数据的方法。OOP的核心概念包括类、对象、继承、封装和多态。

类(Class)

类是创建对象的蓝图或模板。它定义了对象将拥有的属性(数据)和方法(行为)。类可以看作是创建对象的“工厂”。

对象(Object)

对象是类的实例。每个对象都有自己的属性和方法的副本。对象是实际存在于程序中的实体,可以接收消息、处理数据和发送消息。

继承(Inheritance)

继承是面向对象编程中的一种机制,它允许一个类(子类)继承另一个类(父类)的属性和方法。这有助于代码复用和创建一个层次化的类结构。

封装(Encapsulation)

封装是将数据(属性)和操作数据的代码(方法)绑定在一起的过程,形成一个独立的对象,并对外隐藏对象的实现细节。封装的目的是保护对象内部的状态,只通过公共的接口与外界交互。

多态(Polymorphism)

多态是指允许不同类的对象对同一消息做出响应的能力。在OOP中,多态通常通过继承和接口实现。多态使得代码更加灵活和可扩展。

TypeScript中的类和对象

类的定义和使用

在TypeScript中,类是创建对象的蓝图。类定义了对象的属性和方法。TypeScript类的定义使用class关键字,可以包含属性、构造函数、方法等。

class Person {// 类属性name: string;age: number;// 构造函数constructor(name: string, age: number) {this.name = name;this.age = age;}// 类方法greet() {console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);}
}

对象的创建和属性访问

使用new关键字可以创建类的实例,即对象。通过对象,可以访问类的属性和方法。

const person = new Person('Alice', 30);
person.greet(); // 输出: Hello, my name is Alice and I am 30 years old.

类的构造函数和方法

构造函数

构造函数是类的一个特殊方法,它在创建对象时自动调用。构造函数用于初始化对象的属性。

class Rectangle {width: number;height: number;constructor(width: number, height: number) {this.width = width;this.height = height;}
}
方法

类的方法定义了对象可以执行的操作。方法可以访问类的属性和执行逻辑。

class Circle {radius: number;constructor(radius: number) {this.radius = radius;}// 计算圆的面积calculateArea(): number {return Math.PI * this.radius * this.radius;}
}

类的访问修饰符

TypeScript支持访问修饰符,用于控制类成员的可见性:

  • public(默认):成员可以在任何地方被访问。
  • private:成员只能在类的内部被访问。
  • protected:成员可以在类及其子类中被访问。
class Vehicle {private brand: string;constructor(brand: string) {this.brand = brand;}// 只能在类内部访问private displayBrand() {console.log(`Vehicle brand: ${this.brand}`);}
}const vehicle = new Vehicle('Toyota');
// vehicle.displayBrand(); // 错误:Property 'displayBrand' is private and only accessible within class 'Vehicle'.

类的静态成员

静态成员属于类本身,而不是类的实例。静态成员通过static关键字定义。

class Utility {static PI = 3.14159;static calculateCircumference(radius: number) {return 2 * Utility.PI * radius;}
}console.log(Utility.calculateCircumference(5)); // 输出: 31.4159

 总的来说,我认为类就是一个可以快捷的,可以快速创造出有相同特征的对象的工厂

TypeScript的继承

继承的基本概念

继承允许子类继承父类的属性和方法,这样子类就可以使用父类的代码,而不需要重新编写相同的代码。继承是面向对象编程中实现代码复用的一种方式。

使用extends关键字实现继承

在TypeScript中,使用extends关键字来创建一个类的子类。子类继承父类的所有属性和方法,并且可以添加新的属性和方法或者重写父类的方法。

class Animal {name: string;constructor(name: string) {this.name = name;}speak() {console.log(`${this.name} makes a noise.`);}
}class Dog extends Animal {// Dog类继承了Animal类的属性和方法speak() {console.log(`${this.name} barks.`);}
}

方法重写和super关键字的使用

在子类中,我们可以通过重写方法来提供特定于子类的实现。如果子类需要调用父类的方法,可以使用super关键字。

class Cat extends Animal {speak() {console.log(`${this.name} meows.`);}// 调用父类的speak方法makeNoise() {super.speak(); // 输出: Cat name makes a noise.console.log(`${this.name} also meows.`);}
}

在上面的例子中,Cat类重写了Animal类的speak方法,并且在makeNoise方法中使用super.speak()调用了父类的speak方法。

继承的其他特性

  • 构造函数的继承:如果子类有构造函数,它必须首先调用super()来调用父类的构造函数。
  • 访问修饰符:在子类中,可以使用publicprotectedprivate访问修饰符来控制继承的属性和方法的可见性。
  • 静态成员的继承:子类可以继承父类的静态成员。

他的存在有什么意义呢?我们可以通过一个比较广泛的类来扩展出他的一些子类,比如说我有一个类叫‘动物’,  然后我想创建 ‘狗’, ‘猫’,通过继承‘动物’来创建类的话就不用重新把‘动物’的属性与方法重写一遍了,直接继承就可以了,这样可以少些很多代码

TypeScript的封装

封装的意义和实现方式

封装的意义在于:

1.数据隐藏:通过封装,可以隐藏对象的内部状态,只暴露必要的操作接口给外部,从而保护对象的数据不被外部直接访问和修改。

2.模块化:封装有助于将代码组织成独立的模块,每个模块负责自己的数据和操作,使得代码更加模块化和易于管理。

3.灵活性:封装允许对象的内部实现细节发生变化,而不会影响到使用该对象的外部代码,提高了代码的灵活性和可维护性。

在TypeScript中,实现封装的方式主要是通过访问修饰符来控制属性和方法的可见性。

访问修饰符的使用

TypeScript提供了以下访问修饰符:

  • public:默认修饰符,表示成员可以在任何地方被访问。
  • private:表示成员只能在类的内部被访问。
  • protected:表示成员可以在类及其子类中被访问。

属性和方法的封装

在TypeScript中,我们可以通过访问修饰符来封装属性和方法:

class Person {private name: string; // 私有属性,只能在类内部访问constructor(name: string) {this.name = name;}public getName(): string { // 公有方法,可以在类外部访问return this.name;}protected getInternalName(): string { // 受保护的方法,只能在类及其子类中访问return `Internal Name: ${this.name}`;}
}class Employee extends Person {public getEmployeeName(): string {return this.getInternalName(); // 子类可以访问受保护的方法}
}const person = new Person('Alice');
console.log(person.getName()); // 输出: Alice
// console.log(person.name); // 错误:Property 'name' is private and only accessible within class 'Person'.

TypeScript的封装

多态的概念和重要性

多态(Polymorphism)意味着“多种形态”。在编程中,它指的是同一个操作作用于不同的对象,可以有不同的解释和不同的执行结果。多态允许我们使用通用的接口来操作不同类型的对象,从而提高代码的可复用性和可维护性。

多态的重要性体现在:

1.代码复用:通过多态,我们可以编写通用的代码来处理不同类型的对象,减少了代码的重复。

2.可扩展性:多态使得添加新的对象类型变得更加容易,因为它们可以遵循已有的接口。

3.灵活性:多态允许我们延迟绑定,即在运行时确定对象的类型和方法的实现,增加了程序的灵活性。

抽象类和接口的使用

在TypeScript中,多态通常通过抽象类和接口来实现。

抽象类

抽象类是不能被实例化的类,它通常包含一个或多个抽象方法。抽象方法是只有声明没有具体实现的方法,它们必须在子类中被实现。

abstract class Animal {abstract makeSound(): void; // 抽象方法move(): void {console.log('Animal moves');}
}class Dog extends Animal {makeSound(): void {console.log('Dog barks');}
}const dog = new Dog();
dog.makeSound(); // 输出: Dog barks
dog.move(); // 输出: Animal moves
接口

接口定义了一组方法的规范,但不提供这些方法的具体实现。类可以实现一个或多个接口,这意味着类必须实现接口中定义的所有方法。

interface Singer {sing(): void;
}class Musician implements Singer {sing(): void {console.log('Musician is singing');}
}const musician = new Musician();
musician.sing(); // 输出: Musician is singing

实现多态的示例

多态通常通过继承和接口实现。下面是一个使用抽象类和接口实现多态的示例:

interface Vehicle {start(): void;
}abstract class Car implements Vehicle {abstract start(): void;
}class ElectricCar extends Car {start(): void {console.log('Electric car starts silently');}
}class PetrolCar extends Car {start(): void {console.log('Petrol car starts with engine noise');}
}const electricCar = new ElectricCar();
electricCar.start(); // 输出: Electric car starts silentlyconst petrolCar = new PetrolCar();
petrolCar.start(); // 输出: Petrol car starts with engine noise

TypeScript 泛型

泛型的基本概念

泛型可以理解为类型变量,它代表了一个或多个类型。在定义泛型时,你可以使用一个或多个类型变量来表示这些类型。这些类型变量在使用时会被实际的类型所替换。

泛型的使用

泛型函数

泛型函数允许你定义一个或多个类型参数,这些类型参数在函数被调用时会被指定。

function identity<T>(arg: T): T {return arg;
}let output = identity<string>("myString");
// 或者使用类型推断
let output = identity("myString");

在这个例子中,identity函数有一个类型参数T,它表示函数可以接受任何类型的参数,并返回相同类型的值。

泛型接口

泛型接口允许你定义一个或多个类型参数,这些类型参数在实现接口时会被指定。

interface GenericIdentityFn<T> {(arg: T): T;
}function identity<T>(arg: T): T {return arg;
}let myIdentity: GenericIdentityFn<number> = identity;

在这个例子中,GenericIdentityFn是一个泛型接口,它有一个类型参数Tidentity函数实现了这个接口,并指定了Tnumber类型。

泛型类

泛型类允许你定义一个或多个类型参数,这些类型参数在创建类的实例时会被指定。

class GenericNumber<T> {zeroValue: T;add: (x: T, y: T) => T;
}let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

在这个例子中,GenericNumber是一个泛型类,它有一个类型参数T。创建GenericNumber类的实例时,必须指定T的类型。

泛型约束

泛型约束允许你限制可以用于泛型参数的类型。通过使用extends关键字,你可以指定泛型参数必须满足的接口。

interface Lengthwise {length: number;
}function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length);  // Now we know it has a .length property, so no more errorreturn arg;
}

在这个例子中,loggingIdentity函数有一个泛型参数T,它必须满足Lengthwise接口,即必须有一个length属性。

泛型的好处

使用泛型可以带来以下好处:

  • 类型安全:泛型确保在编译时检查类型,避免类型错误。
  • 代码复用:泛型允许你编写可适用于多种数据类型的代码,提高代码的复用性。
  • 灵活性:泛型使得函数、接口或类可以灵活地处理不同类型的数据,而不需要为每种类型编写重复的代码。

总结

TypeScript结合OOP特性如类、继承、封装、多态和泛型,提供了强大的工具集来构建可维护、可扩展和类型安全的应用程序。

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

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

相关文章

单例模式_Golang

目录 一、单例模式 1.1 基本概念 1.2 使用场景 二、Golang实现 2.1 懒汉模式&#xff08;Lazy Loading&#xff09; 一、单例模式 1.1 基本概念 一个类只能生成一个实例&#xff0c;且该类能自行创建这个实例的一种模式,这个定义个人感觉可以拆的通俗一些,在项目的生命周…

电子电器架构 - SOA架构软件平台

电子电器架构 - SOA架构软件平台 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无…

Spring通过工厂方法进行配置

在Spring的世界中&#xff0c; 我们通常会利用 xml配置文件 或者 annotation注解方式来配置bean实例&#xff01; 在第一种利用 xml配置文件 方式中&#xff0c; 还包括如下三小类 反射模式&#xff08;我们前面的所有配置都是这种模式&#xff09;工厂方法模式Factory Bean模…

Composition API实现逻辑复用

抽离逻辑代码到一个函数函数命名约定为useXxxx格式&#xff08;react Hooks也是&#xff09;在setup中去引用这个函数 如下经典鼠标位置例子&#xff1a; // useMousePosition.ts import { onMounted, onUnmounted, ref } from "vue";const useMousePosition () &…

【Spark官方文档部分翻译】RDD编程指南(RDD Programming Guide)

写在前面 内容如何选择 本翻译只翻译本人认为精华的部分&#xff0c;本人认为的Spark的一些核心理念&#xff0c;编程思想。一些特别基础的操作包括但不限于搭建环境就不在此赘述了。 配套版本 本系列基于Spark 3.3.1&#xff0c;Scala 2.12.10&#xff0c;进行翻译总结 原…

Linux+InternStudio 关卡(test)

任务地址&#xff1a; https://github.com/InternLM/Tutorial/blob/camp3/docs/L0/Linux/task.md 文档 https://github.com/InternLM/Tutorial/blob/camp3/docs/L0/Linux/readme.md 任务 ssh连接 端口映射 gradio页面 笔记&#xff1a; 1.端口映射阶段&#xff1a;输入密…

编译linux kernel时,如何增加一个include路径?

编译linux kernel时增加一个include路径的方法&#xff0c;使用 EXTRA_CFLAGS : make O/path/to/build/dir ARCHyour_arch CROSS_COMPILEyour_cross_compiler EXTRA_CFLAGS"-I/your/new/path" 其中 EXTRA_CFLAGS"-I/your/new/path" 就是要增加的include路径…

线段树分治+可撤销并查集 学习笔记

题目一般是给你边或者点的出现时间区间[Li,Ri]&#xff0c;问你在某些时间里1能访问到的点或者点的数量。 先考虑暴力的思路&#xff0c;就是对于一个具体的时间节点&#xff0c;我们去暴力地得知当前边/点是否出现&#xff0c;并且跑图查看是否联通。 由于一个具体的时间节点…

使用 hutool工具实现导入导出功能。

hutool工具网址 Hutool参考文档 pom依赖 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.20</version></dependency><dependency><groupId>org.apache.poi</gro…

ASP.NET Core在启动过程中使用数据库实例的几种方式

ASP.NET Core项目启动过程中若要调用SqlSugarClient实例操作数据库数据&#xff08;假设操作函数如下&#xff09;&#xff0c;特此记录以下几种方式&#xff1a; public class PublicDataBuffer {public static List<EnvironmentRecord> DataBuffer new List<Envir…

【BUG】已解决:ModuleNotFoundError: No module named ‘sklearn‘

已解决&#xff1a;ModuleNotFoundError: No module named ‘sklearn‘ 目录 已解决&#xff1a;ModuleNotFoundError: No module named ‘sklearn‘ 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是…

Kotlin 基础语法

文章目录 一. 函数 一. 函数 Java中方法的叫法更普遍一些&#xff0c;Kotlin中函数的叫法更普遍一些&#xff1b;二者为同一东西 1. 标准写法 fun largerNumber(num1: Int, num2: Int): Int {return max(num1, num2) }2. 重要语法糖 当一个函数中只有一行代码时&#xff0c;K…

视频点播项目

文章目录 视频点播技术栈与项目环境JsonCppMariaDBhttplib 工具类设计文件类Json类 数据管理模块视频信息管理&#xff08;数据表设计&#xff09;数据管理类设计 网络通信接口设计业务处理模块设计前端界面主页面播放页面 项目总结项目回顾项目结构关键技术点总结 视频点播 允…

亚马逊自发货erp,虚拟自动化发货功能以及1688订单采购

亚马逊自发货erp自动化功能&#xff0c;自动同步订单&#xff0c;1688订单同步。 大家好&#xff0c;今天分享一个非常实用并且节省时间的功能&#xff1a;自动化发货以及1688同步订单。 首先来看下自动化发货功能怎么操作。 →要在商品信息里面添加商品信息&#xff0c;上传…

ubuntu系统下安装配置 8.0.37的MySQL

ubuntu系统下安装配置MySQL 8.0.37-0ubuntu0.22.04.3服务 安装mysql sudo apt update sudo apt install mysql-server sudo systemctl status mysql进入mysql&#xff0c;创建特定用户&#xff0c;专门用于登录 sudo mysql; create user user_nameip_address identified by …

风灵月影修改器未检测到游戏怎么回事?解决方法分享

当风灵月影修改器未检测到游戏进程时&#xff0c;可能是由以下几个原因导致的&#xff1a; 1. 游戏未启动&#xff1a; 最直接的原因就是游戏本身没有被启动&#xff0c;或者游戏还未完全加载完成&#xff0c;处于启动过程中的某个阶段&#xff0c;此时修改器可能检测不到游戏…

【总结】逻辑运算在Z3中运用+CTF习题

国际赛IrisCTF在前几天举办&#xff0c;遇到了一道有意思的题目&#xff0c;特来总结。 题目 附件如下&#xff1a;&#x1f4ce;babyrevjohnson.tar 解题过程 关键main函数分析如下&#xff1a; int __fastcall main(int argc, const char **argv, const char**envp){int v4…

【优质精选】12节大模型系列教学课程-更新中001

欢迎踏上这一精彩纷呈的大模型知识之旅&#xff01;这一系列课程是为了帮助您全面、深入地理解和掌握大模型领域的核心知识与前沿技术而精心设计的。 从基础概论开始&#xff0c;为您搭建起扎实的知识框架&#xff0c;让您对大模型的来龙去脉有清晰的认知。深入剖析 RAG、SFT、…

关于adcoder和codeforce 如何安装翻译插件

首先在扩展当中下载插件篡改猴 其次&#xff0c;点击获取新的脚本 最后搜索 atcoder better 和 codeforce better 安装即可

【Spring Boot】网页五子棋项目实现,手把手带你全盘解析(长达两万3千字的干货,坐好了,要发车了......)

目录 网页五子棋项目一、项目核心流程二、 登录模块2.1 前端输入用户信息2.2 后端进行数据库查询用户信息 三、 游戏大厅模块3.1 前端通过Ajax请求用户数据&#xff0c;后端从Session中拿取并从数据库中查询后返回3.2 前后端建立WebSocket连接&#xff0c;并进行判断&#xff0…