typescript - class

class

类的定义

虽然JavaScript语言支持了类,但是本质上是函数,类是一种语法糖,typescript语言对于JavaScript的类进行了拓展,为其添加了类型支持。类的定义有两种方式:1. 类声明 2. 类表达式

类声明

class ClassName {// ...
}

在该语法中,class是关键字,ClassName表示类的名称,在类的声明中类名是必选的

class Circle {radius: number
}
const c = new Circle()

类声明不会提升,因此必须先声明后使用,在使用类声明的时候,不允许声明同名的类,否则将产生错误

类表达式

类表达式是一种定义类的方式

const Name = class ClassName {//...
}

在这个语法中,class是关键字,Name表示引用了该类的变量名

const Circle = class {radius: number
}
const a = new Circle()

如果在类表达式中定义了类名,则该类名只能在类内部使用,在类外不允许使用该类名

const A = class B {name = B.name
}
const b = new B()

成员变量

在类中定义成员变量的方法如下

class Circle {raduis: number = 1
}
class Circle_a {radius: number ;constructor() {this.radius = 1        }
}

在此例中,在构造函数中将radius成员变量的值初始化为1, 同时注意,在构造函数中引用成员变量的时候需要使用this关键字。

readonly属性

添加readonly属性的时候,能够将该成员变量声明为只读的,只读变量必须在声明的时候初始化或者构造在函数里面

class A {readonly a = 0;readonly b: number;readonly c: number; // errorconstructor () {this.b = 0 }
}

成员函数

成员函数也称为方法,声明成员函数在与对象字面量中的声明方法是类似的。

class Circle {radius: number = 1;area() :number {return 1}
}

成员存取器

成员存取器由get和set方法构成,并且会在类中声明一个属性。

class C {private _foo: number;get foo() {return this._foo}set foo(value: number) {}
}

如果有一个类属性同时定义了get方法和set方法,那么get方法和set方法中必须具有相同的可访问性。
存取器是实现数据封装的一种方式,提供了一层额外的访问控制。类可以将成员变量的访问权控制在类的内部,在类的外部通过存取器方法来间接的访问成员变量。

索引成员

类的索引成员会在类的类型中引入索引签名,索引签名必须包含两种,分别为字符串签名和数值索引签名。类中所有的属性和方法必须符合字符串索引签名定义的类型。

class A {x: number = 0[prop: string]: number;[prop: number]: number;
}

在类的索引上不允许定义可访问修饰符

成员可访问性

  • public
    类的公有成员没有访问限制,可以在当前类的内部,外部以及派生类的内部访问,类的公有成员使用public修饰符,在默认情况下,类的所有成员都是公有成员,因此,在定义公有成员的时候也可以定义public修饰符
  • protected
    类的受保护成员允许在当前类的内部和派生类的内部访问,但是不允许在当前类的外部访问,类的受保护成员使用protected修饰符表示。
  • private
    类的私有成员只允许在当前类的内部进行访问,在当前类的外部以及派生类的内部不允许进行访问,类的私有成员使用private修饰符标识
  • 私有字段
    在字段标识符前面添加一个#符号,不论是在定义私有字段还是在访问私有字段的时候,都不要在私有字段名字前面添加一个#符号
class Circle {#radius: number;constructor() {this.#radius = 1}
}
const circle = new Circle();
circle.#radius ; // 不允许被访问

构造函数

构造函数用于创建和初始化类的实例,当使用new运算符调用一个类的时候,类的构造函数就会被调用,构造函数以constructor作为函数名

class Circle {
radius: number;
constructor(r: number) {
this.radius = r;}
}
const c = new Circle(1);

和普通函数相同,在构造函数中也可以定义可选参数,默认值参数和剩余参数,但是构造函数中不允许定义返回值类型,因为构造函数的返回值类型永远为类的实例类型。

class A {constructor(a: number = 0, b ?: boolean, ...c: string[]) {}
}
class B {constructor(): object{} // 编译错误,不允许指定构造函数的返回值类型
}

在构造函数上可以使用可访问性修饰符,允许使用该类型来创建实例对象,在默认的情况下,构造函数是公有的,如果将构造函数设置成为私有的,只允许在类的内部创建该类的对象。

class Singleton {private static instance?: Singleton;private constructor() {if (!Singleton.instance) {Singleton.instance = new Singleton()}return SIngleton.instance}
}
new Singleton()

与函数重载类型,构造函数也支持重载,将没有函数体的构造函数声明为构造函数重载,同时定义了函数体的构造函数声明称为构造函数实现。

class A {constructor(x: number, y: number) ;constructor(s: string);constructor(xs: number | string, y?: number) {}
}
const a = new A(0, 0)
const b = new A('foo')

参数成员

typescript提供了一种简洁语法能够把构造函数的形式参数声明为类的成员变量,称为参数变量,在构造函数类型列表中,为形式参数添加了一个可访问性修饰符或者readonly修饰符,该形式参数就成了参数成员,进而会被声明为类的成员变量

class A {constructor(public x: number) {}
}
const a = new A(0)
a.x // 0

继承

继承是面向对象程序设计的三个基本特征之一,typescrpt中的类也支持继承,在定义了id时候可以使用extends关键字来指定要继承的类

class DerivedClass extends BaseClass {}

BaseClass称为基类, DerivedClass称为派生类。派生类继承了基类。派生类继承了基类的非私有成员。
在派生类中,可以通过super关键字来访问基类中的非私有成员。在派生类中只能通过super关键字来访问积累中的菲斯有成员,无法使用this关键字来引用积累中的非私有成员。
若是派生类重写了基类中的受保护成员,则可以将该成员的可访问性设置为受保护的或者公有的。
在派生类的构造函数中必须使用super()语句就能调用积累的构造函数

class Circle extends Shape {radius: number;constructor() {super();this.radius = 1}
}

实例化派生类时的初始化顺序如下

  1. 初始化基类的属性
  2. 调用基类的构造函数
  3. 初始化派生类的属性
  4. 调用派生类的构造函数
    typescript中的类仅仅支持单继承,不支持多继承,在extends语句中只能指定一个基类
class A {}
class B {}
class C extends A, B {}

typescript 允许接口继承类,若接口继承了一个类,那么该接口会继承积累中所有成员的类型。
在接口继承类的时候,接口不但回家i成积累的公有成员类型,还会继承类的受保护成员类型和私有成员类型,如果接口从积累继承了非公有成员,那么接口只能由积累或者积累的子类来实现。

class A {x: string = ''y(): boolean {return true}
}
declare const b: B
b.x 
b.y()
class A implenments I {private x: string = ''protected y: string = ''
}
// 接口能够继承a的私有属性和受保护属性
interface I extends A {}
class B extends A implements I {}
class C implements I {} // c不是a的子类,无法实现a的私有属性和受保护属性。 

实现接口

如果类的定义中声明了要实现的接口,那么这个类就需要实现接口中定义的类型成员。

interface A{}
interface B{} 
class C implements A, B {}

静态成员

类的定义中可以包含静态成员,类的静态成员不属于类的某个实例,而是属于类本身,类的静态成员需要使用static关键词定义,并且只允许通过类名来访问。

class Circle {static version: string = '1.0'
}
const version = Circle.version
circle .version  // version是Circle类的静态属性

类的静态成员也可以定义不同的可访问性,比如public,private和protected
类的pulic静态成员对访问没有限制,可以在当前类的内部,外部以及派生类的内部访问
类的protected静态成员允许在当前类的内部和派生类的内部访问,但是不允许在当前类的外部访问
类的private静态成员只允许在当前类的内部访问
类的public静态成员和protected静态成员也可以被继承。

class Base {public static x: string = ''protected static y: string = ''
}
class Derived extends Base {b() {Derived.x;// 继承了基类的静态成员xDerived.y;// 继承了基类的静态成员y}
}

抽象类和抽象成员

abstract class A {}

抽象类不能被实例化,也就是说,不允许使用new运算符来创建一个抽象类的实例。抽象类主要是作为基类使用,派生类可以继承抽象类。
抽象类可以继承其他抽象类。

abstract class Base{}
abstract class Derived extends Base {}

在此例中,基类和派生类都是抽象类,不能被实例化。抽象类允许包含抽象成员,也允许包含非抽象成员。

abstract class Base {abstract a: string;b: string = ''
}

在抽象类中声明抽象成员,抽象成员不允许包含具体实现代码。如果一个具体类继承了抽象类,在具体的派生类中必须实现抽象类基类中的所有抽象成员,因此抽象类中的抽象成员能不能声明为private,否则将无法在派生类中实现该成员。

abstract class Base {abstract a: string;abstract get accessor(): string;abstract set accessor(value: string);abstract methond(): boolean;
}
class Derived extends Base {a: string = 'd';private _accessor: string = '';get accessor(): string {return this._accessor}set accessor(value: string) {this._accessor = value}method(): boolean {return true}
}

this类型

在类中存在一种特殊的this类型,表示当前this值的类型,我们可以在类的非静态成员的类型注解中使用this类型,

class Counter {private count: number = 0;public add(): this {this.count++;return this}public subtrace(): this{this.count--;return this}public getResult():number {return this.count}
}
const counter = new Counter();
counter.add().add().substarct().getResult()

this类型是动态的,表示当前this值的类型,当前this值的类型不一定是引用了this类型的那个类,该差别主要是体现在类之间有继承关系的时候

class A {foo(): this {return this;}
}
class B extends A {bar(): this {return this}
}
const b = new B();
const x = b.bar().foo() // 类型为B

this类型不允许应用于类的静态成员

class A {static a : this; // 编译错误,this类型只能用于类的非静态成员
}

类类型

class A {static x : number = 0;y: number = 0;
}
const a: A = new A() // 类类型,即实例类型
interface AConstructor {new (): A;x: number;
}
const b: AConstructor = A  // 类构造函数类型

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

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

相关文章

C#发送邮件的SMTP配置方法?如何群发邮件?

C#发送邮件安全性如何保障?C#怎么配置实现发送邮件? 在C#开发中,发送电子邮件是一个常见的需求。无论是用于注册确认、密码重置还是其他通知功能,SMTP(简单邮件传输协议)都是实现这一功能的关键。下面&…

Shell脚本学习_内置命令

目录 1.内置命令介绍: 2.Shell内置命令:alias设置别名 3.Shell内置命令:echo输出字符串 4.Shell内置命令:read读取控制台输入 5.Shell内置命令:exit退出 6.Shell内置命令:declare设置变量 1.内置命令…

Web前端标签怎么用:探索与解析标签的奥秘

Web前端标签怎么用:探索与解析标签的奥秘 在浩瀚的Web世界中,前端标签作为构建网页的基础元素,承载着呈现内容、实现交互的重要使命。那么,Web前端标签究竟怎么用呢?让我们一同深入探索这个充满奥秘的领域。 一、标签…

kali2022安装教程(附安装包)

第一步:下载镜像文件 百度网盘下载https://pan.baidu.com/s/1efRQGFTbq6Kgw9axLOmWzg?pwdemxf 第二步:打开Vmware 第三步:进行各项配置 创建新的虚拟机,选择高级,然后下一步 直接默认下一步 选择稍后安装然后下…

C++程序打开EXCEL2010失败,提示:远程过程调用失败

前两天将Foxit福昕PDF阅览器升级到了最新版本,导致了这个问题,参照这篇文章才知道是升级了福昕阅读器引起的: c#调用excel报错(异常来自HRESULT:0X80010105(RPC_SERVERFAULT)) 这个问题折腾了很久才搞定,网上的很多办法都不靠谱…

设计软件有哪些?效果工具篇(3),渲染100邀请码1a12

这次我们再介绍一批渲染效果和后期处理的工具。 1、ColorCorrect ColorCorrect是一种图像处理技术,用于调整图像的色彩和对比度,使其更加自然和平衡。通过ColorCorrect,用户可以调整图像的色调、亮度、饱和度等参数,以达到理想的效…

kube-promethesu调整coredns监控

K8s集群版本是二进制部署的1.20.4,kube-prometheus对应选择的版本是kube-prometheus-0.8.0 Coredns是在安装集群的时候部署的,采用的也是该版本的官方文档,kube-prometheus中也有coredns的监控配置信息,但是在prometheus的监控页…

kivy 百词斩项目 报错

AttributeError: FigureCanvasKivyAgg object has no attribute resize_event AttributeError: FigureCanvasKivyAgg object has no attribute resize_event 是一种常见的Python错误,当你试图访问一个对象(在这个例子中是 FigureCanvasKivyAgg 对象&am…

二次规划问题(Quadratic Programming, QP)原理例子

二次规划(Quadratic Programming, QP) 二次规划(Quadratic Programming, QP)是优化问题中的一个重要类别,它涉及目标函数为二次函数并且线性约束条件的优化问题。二次规划在控制系统、金融优化、机器学习等领域有广泛应用。下面详细介绍二次规划问题的原理和求解过程 二…

物联网实战--平台篇之(十四)物模型(用户端)

目录 一、底层数据解析 二、物模型后端 三、物模型前端 四、数据下行 本项目的交流QQ群:701889554 物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html 物联网实战--驱动篇https://blog.csdn.net/ypp240124016/category_12631333.html 物联网…

MATLAB数学建模——数据拟合

文章目录 一、简介二、多项式拟合(一)指令介绍(二)代码 三、指定函数拟合(一)指令介绍(二)代码 一、简介 曲线拟合也叫曲线逼近,主要要求拟合的曲线能合理反映数据的基本…

如何有效释放Docker占用的存储空间

随着Docker的广泛应用,我们经常会遇到Docker占用过多存储空间的问题。这可能是由于频繁的镜像拉取、容器创建和删除等操作导致的。本文将介绍几种方法来有效释放Docker占用的存储空间,特别是docker system prune命令的使用。 Docker的存储机制 Docker使…

Linux 36.3 + JetPack v6.0@jetson-inference之目标检测

Linux 36.3 JetPack v6.0jetson-inference之目标检测 1. 源由2. detectnet2.1 命令选项2.2 下载模型2.3 操作示例2.3.1 单张照片2.3.2 多张照片2.3.3 视频 3. 代码3.1 Python3.2 C 4. 参考资料 1. 源由 从应用角度来说,目标检测是计算机视觉里面第二个重要环节。之…

贪心算法05(leetcode435,763,56)

参考资料: https://programmercarl.com/0435.%E6%97%A0%E9%87%8D%E5%8F%A0%E5%8C%BA%E9%97%B4.html 435. 无重叠区间 题目描述: 给定一个区间的集合 intervals ,其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量&#xff…

开源项目学习——vnote

一、介绍 vnote是一款免费且开源的markdown编辑器,用C开发,基于Qt框架,windows/linux/mac都能用。 二、编译 $ git clone --recursive https://github.com/vnotex/vnote.git $ cd vnote && mkdir build $ cd build $ cmake ../ $ …

鲜为人知的英伟达创始人:早早退出,身价不如黄仁勋零头

内容提要 普里姆因为婚姻纠纷等个人生活的干扰无法专注在工作上,在成立公司的10年后,也就是2003年宣布退休离开英伟达,并在2006年出售剩余的所有英伟达股份,过上不与外界联系、离群索居的生活,在家中鼓捣着如何“拯救…

UML交互图-协作图

概述 协作图和序列图都表示出了对象间的交互作用,但是它们侧重点不同。序列图清楚地表示了交互作用中的时间顺序,但没有明确表示对象间的关系。协作图则清楚地表示了对象间的关系,但时间顺序必须从顺序号获得。序列图常常用于表示方案&#…

【云原生】基于windows环境搭建Docker

目录 一、Docker Desktop搭建 二、前置准备 2.1开启 Hyper-V 2.2 Hyper-V选项看不到问题解决 2.3 开启或升级wsl 三、安装过程 3.1 下载安装包 3.2 安装 Docker Desktop 3.2.1 Docker 图标一直处于starting状态问题解决 3.3 配置仓库与镜像 3.4 docker功能测试 四、…

Android studio CPU 唤醒而同时允许屏幕关闭时

在Android中,如果你想在设备屏幕关闭时保持CPU活跃(即不进入深度睡眠),你可以使用PowerManager类来获取一个PARTIAL_WAKE_LOCK。这个WakeLock类型允许设备在屏幕关闭时仍然保持CPU运行和部分硬件(如Wi-Fi)活…

pip install 出现 Missing dependencies for SOCKS support 问题的解决

问题描述 因为要分析chromadb 源码,clone了一份代码到本地后,需要安装依赖,发现有依赖需要python版本低于3.9,于是用anaconda新建了一个3.8的环境. conda create -n chroma python3.8 conda activate chroma创建成功后,进入源码…