TypeScript入门教程 之 类/抽象类/构造器/Getter/Setter
将JavaScript中的类作为头等项很重要的原因是:
- 类提供了有用的结构抽象
- 为开发人员提供一种一致的方式来使用类,而不是使用每个框架(emberjs,reactjs等)提供自己的版本。
- 面向对象的开发人员已经了解类。
最后,JavaScript开发人员可以拥有class
。在这里,我们有一个称为Point的基本类:
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
add(point: Point) {
return new Point(this.x + point.x, this.y + point.y);
}
}
var p1 = new Point(0, 10);
var p2 = new Point(10, 20);
var p3 = p1.add(p2); // {x:10,y:30}
此类在ES5发射上生成以下JavaScript:
var Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.add = function (point) {
return new Point(this.x + point.x, this.y + point.y);
};
return Point;
})();
这是一种相当惯用的传统JavaScript类模式,现在已经成为一种一流的语言构造。
继承
TypeScript中的类(与其他语言一样)使用关键字支持单继承extends
,如下所示:
class Point3D extends Point {
z: number;
constructor(x: number, y: number, z: number) {
super(x, y);
this.z = z;
}
add(point: Point3D) {
var point2D = super.add(point);
return new Point3D(point2D.x, point2D.y, this.z + point.z);
}
}
如果您的类中有构造函数,则必须从构造函数中调用父构造函数(TypeScript会向您指出)。这样可以确保设置需要放置的东西this
。调用之后,super
您可以在构造函数中添加任何您想做的事情(在这里我们添加了另一个member z
)。
请注意,您可以轻松地覆盖父成员函数(在此我们覆盖add
),并且仍在成员中使用父类的功能(使用super.
语法)。
static
TypeScript类支持static
该类的所有实例共享的属性。放置(和访问)它们的自然位置是类本身,而TypeScript就是这样做的:
class Something {
static instances = 0;
constructor() {
Something.instances++;
}
}
var s1 = new Something();
var s2 = new Something();
console.log(Something.instances); // 2
您可以具有静态成员以及静态函数。
访问修饰符
打字稿支持访问修饰符public
,private
以及protected
其中确定的可访问性class
如下所示构件:
可访问 | public | protected | private |
---|---|---|---|
类 | 是 | 是 | 是 |
子类 | 是 | 是 | 没有 |
类实例 | 是 | 没有 | 没有 |
如果未指定访问修饰符,则它是隐式的,public
因为它与JavaScript🌹 的便利性质匹配。
请注意,在运行时(在生成的JS中)这些没有意义,但是如果使用不正确,则会给您带来编译时错误。每个示例如下所示:
class FooBase {
public x: number;
private y: number;
protected z: number;
}
// EFFECT ON INSTANCES
var foo = new FooBase();
foo.x; // okay
foo.y; // ERROR : private
foo.z; // ERROR : protected
// EFFECT ON CHILD CLASSES
class FooChild extends FooBase {
constructor() {
super();
this.x; // okay
this.y; // ERROR: private
this.z; // okay
}
}
与往常一样,这些修饰符对成员属性和成员函数都起作用。
抽象
abstract
可以看作是访问修饰符。我们将其单独呈现,因为与前面提到的修饰符相反,它可以class
位于类的任何成员上。拥有abstract
修饰符主要意味着不能直接调用此类功能,并且子类必须提供该功能。
abstract
类不能直接实例化。相反,用户必须创建一些class
继承自的abstract class
。
abstract class FooCommand {}
class BarCommand extends FooCommand {}
const fooCommand: FooCommand = new FooCommand(); // Cannot create an instance of an abstract class.
const barCommand = new BarCommand(); // You can create an instance of a class that inherits from an abstract class.
abstract
成员不能直接访问,并且子类必须提供功能。
abstract class FooCommand {
abstract execute(): string;
}
class BarErrorCommand extends FooCommand {} // 'BarErrorCommand' needs implement abstract member 'execute'.
class BarCommand extends FooCommand {
execute() {
return `Command Bar executed`;
}
}
const barCommand = new BarCommand();
barCommand.execute(); // Command Bar executed
构造函数是可选的
该类不需要构造函数。例如下面的代码就很好。
class Foo{}
var foo = new Foo();
使用构造函数定义
在班级中拥有一个成员并按如下所示对其进行初始化:
class Foo {
x: number;
constructor(x:number) {
this.x = x;
}
}
这种常见的模式使TypeScript提供了一种简写形式,您可以在该前缀上为成员加上access修饰符,并且该修饰符会在类上自动声明并从构造函数中复制。因此,前面的示例可以重写为(notice public x:number
):
class Foo {
constructor(public x:number) {
}
}
属性初始化器
这是TypeScript(实际上是从ES7)支持的一个漂亮功能。您可以在类构造函数之外初始化该类的任何成员,这对于提供默认值很有用(请注意members = []
)
class Foo {
members = []; // Initialize directly
add(x) {
this.members.push(x);
}
}
翻译来源:https://gitee.com/yunwisdoms/typescript-book/blob/master/docs/classes.md