TypeScript系列教程八《类》

本文详细介绍了JavaScript中的类、访问器(getters和setters)、索引签名、继承机制、访问权限控制、静态成员、泛型以及箭头函数和this的使用,展示了TypeScript中面向对象编程的关键特性。
摘要由CSDN通过智能技术生成

_length = 0;

get length() {

return this._length;

}

set length(value) {

this._length = value;

}

}

注意,没有额外逻辑的字段支持的get/set对在JavaScript中很少有用。如果在get/set操作期间不需要添加额外的逻辑,那么公开公共字段就可以了。

TypeScript对访问器有一些特殊的推理规则:

  • 只有get 没有set ,这个属性自动变成raedonly

  • 如果set 的参数没有明确指出,那么按照get 类型推断

  • Getters and setters必须具有相同的成员可见性(public,private)

class Thing {

_size = 0;

get size(): number {

return this._size;

}

set size(value: string | number | boolean) {

let num = Number(value);

// Don’t allow NaN, Infinity, etc

if (!Number.isFinite(num)) {

this._size = 0;

return;

}

this._size = num;

}

}

索引签名

类可以声明索引签名;它们的工作方式与其他对象类型的索引签名相同:

class MyClass {

[s: string]: boolean | ((s: string) => boolean);

check(s: string) {

return this[s] as boolean;

}

}

因为索引签名类型还需要捕获方法的类型,所以很难有效地使用这些类型。一般来说,最好将索引数据存储在另一个地方,而不是类实例本身。

类的实现和继承


与其他具有面向对象特性的语言一样,JavaScript中的类可以从基类继承。

implements

一个类可以准守一个或者多个接口去实现它:

interface Pingable {

ping(): void;

}

class Sonar implements Pingable {

ping() {

console.log(“ping!”);

}

}

class Ball implements Pingable {

//Class ‘Ball’ incorrectly implements interface ‘Pingable’.

//Property ‘ping’ is missing in type ‘Ball’ but required in type ‘Pingable’.

pong() {

console.log(“pong!”);

}

}

类同时可以准守多个接口取实现,例如 class C implements A, B {

可选值不会要求,实现类去实现:

interface A {

x: number;

y?: number;

}

class C implements A {

x = 0;

}

const c = new C();

c.y = 10;

Property ‘y’ does not exist on type ‘C’.

extends (继承)

类可以从基类扩展。派生类具有其基类的所有属性和方法,还定义其他成员。

class Animal {

move() {

console.log(“Moving along!”);

}

}

class Dog extends Animal {

woof(times: number) {

for (let i = 0; i < times; i++) {

console.log(“woof!”);

}

}

}

const d = new Dog();

// Base class method

d.move();

// Derived class method

d.woof(3);

方法重写

子类继承父类之后,可以重写属性和方法

class Base {

greet() {

console.log(“Hello, world!”);

}

}

class Derived extends Base {

greet(name?: string) {

if (name === undefined) {

super.greet();

} else {

console.log(Hello, ${name.toUpperCase()});

}

}

}

const d = new Derived();

d.greet();

d.greet(“reader”);

面向对象的特征父类可以指向子类(变量多态):

// Alias the derived instance through a base class reference

const b: Base = d;

// No problem

b.greet();

初始化顺序

在某些情况下,JavaScript类的初始化顺序可能令人惊讶。让我们来考虑这个代码:

class Base {

name = “base”;

constructor() {

console.log("My name is " + this.name);

}

}

class Derived extends Base {

name = “derived”;

}

// Prints “base”, not “derived”

const d = new Derived();

这里发生了什么?

JavaScript定义的类初始化顺序是:

  • 基类字段已初始化

  • 基类构造函数运行

  • 派生类字段已初始化

  • 派生类构造函数运行

这意味着基类构造函数在自己的构造函数中看到了自己的name值,因为派生类字段初始化尚未运行。

类成员访问权限

您可以使用TypeScript来控制某些方法或属性是否对类之外的代码可见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值