目录
需求
准备开始
一个快速的旁注
构造函数
这是100篇系列文章的第3部分,如果你以前没有使用过TypeScript,这篇文章将向你介绍它;如果你用过它,它会让你复习你已经知道的东西,也许还会给你介绍一些你以前可能没有遇到过的新东西。在本部分中,您将更深入地了解类,学习如何添加我们自己的构造函数,以及更改类外的代码是否可以看到我们的字段。
欢迎回到学习TypeScript从基础到高级内容的系列文章。第2天,我们学习了如何使用TypeScript创建一个简单的类。今天,我们将更深入地探索类,展示如何添加自己的构造函数,以及如何更改类外的代码是否可以看到我们的字段。
需求我必须承认,我对写一个简单的加法类有点厌倦了,所以我要写一个有更多内容的类。今天,我要写一个Point类。作为一名专业开发人员,我想知道我想让我的类做什么,所以我将给出以下要求。
这个类将允许我添加一个 x和一个 y值来表示单个点。
- 这个类将为我提供一个IsEmpty方法,这样我就可以确定x和y 是否没有被设置为0,0。
- 改变x和y值的唯一方法是通过Offset方法。
- 我将能够添加一个Point到一个点以得到一个新的点。
- 我可以通过IsEqual方法确定两个点是否相等(具有相同的坐标)。
- 我将有一个ToString方法,它会告诉人们使用类的x和y值是什么。
今天练习的代码可以在 这里找到如果您查看代码,您将看到我已经创建了一个tsconfig.json文件。这是我为第2天和第1天创建的文件,所以你可以复制你之前创建的文件或添加一个新的使用:
tsc --init
在我的day3.ts类中,我将从创建基本的类结构开始。
class Point {
}
您可能会想,为什么还没有见过任何名为object的东西,但我一直在谈论面向对象编程。我见过很多复杂的解释,但有一个很简单的解释。当我们说到对象时,我们说的是应用程序在运行时创建的东西;类是对象的模板,因此当我们创建类的新实例时(实例化类是您可能看到的另一个术语),我们实际上创建了一个对象。我们可以用数千个类编写一个程序;在我们真正从它们创建实例之前,它们是没有用的。
构造函数当我们创建正在编写的任何类的实例时,您可以把它看作是在构造类。为了帮助我们构造实例,我们有一个叫做构造函数的特殊方法。这个方法特别有趣,因为它帮助我们将实例放到可以使用它的开始位置,因此它可以对类被实例化时发生的事情产生很大的影响。因为这个方法是用来构造实例的,所以你不能直接从TypeScript调用它。唯一与之直接交互的是new关键字。构造函数是什么样子的呢?
在TypeScript中, 构造函数会像这样使用constructor关键字:
constructor() {
}
提示:如果构造函数是这样的,可以删除它。如果您没有向类中添加构造函数,则会自动为您“添加”一个类似这样的构造函数。您不会在代码中看到它,但它确实存在。这就是我没有在第二天的代码中添加构造函数的原因。
在我的要求中,我说这个类允许我添加x和y值来表示这个点。为了做到这一点,我将像这样将这些值传递到构造函数中:
constructor(x: number, y: number) {
}
有了这个,我需要创建这个类的实例的任何地方,我可以像这样创建它:
class Point {
constructor(x: number, y: number) {
}
}
const point: Point = new Point(0, 0);
注意:因为我已经添加了带参数的构造函数,所以我不再有访问默认构造函数的权限,所以我不得不在这里使用带参数的构造函数。
我已经传递了值,但实际上我并没有对它们做任何事情。它们对任何需要它们的方法都不可用,因为它们只对构造函数可见。我将通过添加两个字段来存储这些值来修复这个问题。我的一个要求是,更改字段值的唯一方法是使用Offset方法,所以这意味着我不应该从类外部直接访问它们。为此,我将引入private关键字。private的作用是告诉编译器这个字段只在类内部可见。
你可能会想,我们不能把一切都变成private,这是正确的。默认情况下,TypeScript将类中的内容设置为public,但你也可以显式地将内容设置为public。
我们的private字段看起来像这样:
private x: number;
private y: number;
如果你还记得,在第2天,我必须给我们的字段分配一个默认值,当我创建它们的时候。当我在构造函数中给它们赋值时,编译器足够聪明,知道我不必给它们赋值。我的构造函数现在看起来像这样:
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
即将到来的。在以后的文章中,我将向您展示一个方便的TypeScript技巧,我可以在构造函数的签名中声明一个字段。
现在我要谈谈我的其他要求。让我们从检查一个点是否为空的能力开始。我在这里做了一个决定,空点是x和y值都被设为0的点。
public IsEmpty(): boolean {
return this.x === 0 && this.y === 0;
}
下一个方法是检查两点是否相等。在这种情况下,等号是指两个点的x值是否相同,y值是否相同。因为这段代码将在类的实例中运行,所以我只需要传入我想要比较的Point。
public IsEqual(point: Point): boolean {
return this.x === point.x && this.y === point.y;
}
通过这样少量的代码增量,我可以快速地添加所需的所有功能。偏移坐标的能力如下所示:
public Offset(x: number, y: number) {
this.x = this.x + x;
this.y = this.y + y;
}
重要提示: 有一种简便的方法可以将另一个值添加到现有值中。如果我在我的代码中使用+=,我可以改变
this.x = this.x + x;
为
this.x += x;
我将在这里添加整个类,而不是介绍其他方法,这样您就可以看到ToString和Add方法是什么样子的。到目前为止,您应该已经很好地了解了这些方法可能会做什么。
class Point {
private x: number;
private y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
public IsEmpty(): boolean {
return this.x === 0 && this.y === 0;
}
public IsEqual(point: Point): boolean {
return this.x === point.x && this.y === point.y;
}
public Add(point: Point): Point {
return new Point(point.x + this.x, point.y + this.y);
}
public ToString(): string {
return 'X is ' + this.x + ' Y is ' + this.y;
}
public Offset(x: number, y: number): void {
this.x += x;
this.y += y;
}
}
如果我想演示这段代码的操作,我可以这样写:
const point: Point = new Point(0, 0);
console.log('Point is empty is ' + point.IsEmpty()); // Should be true
point.Offset(10, 20);
console.log('Point is empty is ' + point.IsEmpty()); // Should be false
const offsetPoint = new Point(10, 20);
console.log('Points are equal is ' + point.IsEqual(offsetPoint)); // Should be true
console.log('The offset is ' + point.Add(offsetPoint).ToString()); // X is 20 and Y is 40
我们已经完成了第3天的代码。我意识到这里有很多东西可以吸收,从创建自定义构造函数,添加作用域修饰符(public/private)和一点点备用的添加语法。请从Github浏览代码,如果你有任何问题,不要害怕问。第4天,我将向你们介绍TypeScript中的接口。如果你使用过C#或Java这样的语言中的接口,TypeScript让你使用它们的方式简直不可思议。
https://www.codeproject.com/Articles/5316302/100-Days-of-TypeScript-Day-3