目录

Class的基础

Class 的定义

重载

成员函数的重载

Getter/Setter

索引器

组合和继承

类的继承

推荐使用组合或者泛型

成员

类的成员可见域

静态成员【static】

类型的相等

类型守卫【ts做窄化】

抽象类

TS的类型一致(所谓的子类可以赋值给父类)

小结

Class的基础

Class 的定义

class Point {

// ts得先声明一下

x: number

y:number

constructor(x: number, y: number) {

this.x = x

this.y = y

}

public add(p: Point) : Point {

return new Point(p.x + this.x, p.y + this.y)

}

}

const p = new Point(0, 0)

const newP = p.add(new Point(1, 1))

console.log(newP)

重载

成员函数的重载

class Point4 {

  // ts得先声明一下

  x: number

  y: number

  constructor(x: number, y: number) {

    this.x = x

    this.y = y

  }

// class中对成员函数进行重载

  public add(x: number, y: number): Point;

  public add(p: Point): Point;

  public add(x: number | Point, y?: number) {

    if (typeof x === 'number') {

// 因为y是可选项,所有y: number | undefined;写作有!,

// 让null和undefined可以赋值给其他类型并通过编译

      return new Point4(this.x + x, this.y + y!)

    }

    const p = x

    return new Point4(this.x + p.x, this.y + p.y)

  }

}

const p4 = new Point4(0, 0)

const newP4 = p4.add(new Point4(1, 1))

console.log(newP4)

Getter/Setter

class C {

_length = 0;

// ES6语义

get length() {

return this._length;

}

set length(value) {

this._length = value;

}

}

class C {

_length = 0;

// 函数语义

getLength() {

return this._length;

}

setLength(value) {

this._length = value;

}

}

索引器

class Arr {

[i: number]: T // 索引器+类型标注

}

const a = new Arr() // 索引器这个能力可以当成一个数组用,但是不常见

a[10] = 100

console.log(a[10]) // 100

组合和继承

类的继承

class Animal {

move() {

console.log("Moving along!");

}

}

class Dog extends Animal{ // 继承,重度耦合;Dog.move

woof(times: number) {

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

console.log("woof!");

}

}

}

推荐使用组合或者泛型

interface Movable { // 接口

move() : void;

}

class Dog implements Movable { // 组合

move() {

console.log("move dog")

}

}

class Movable { // 泛型

animal:T

move() {

console.log(`${animal.getName()} is moving`)

}

}

成员

类的成员可见域

public公开属性protected保护属性private私有属性

class Point {

public x: number // public

}

// x可以被任意程序访问

class Point {

private x : number

constructor() {

this.x = x // 成立,x是私有的,只有自己的类里面可以用

}

getX() {

return this.x

}

}

const p = new Point()

console.log(p.x) // Error x是私有属性,只有在Point类里面可以用

console.log(p.getX()) // ok

class Animal {

private _name1;

protected _name2;

}

class Dog extends Animal {

getName1(){

return this._name1 // Error 继承类也不能访问私有属性

}

getName2(){

return this._name2 // pass 继承类可以访问保护属性

}

}

静态成员【static】

class MyClass {

static x = 0; //静态成员

static printX() {

console.log(MyClass.x);

}

static name = "S!"// Error name是静态成员的保留字,所以用不了

}

console.log(MyClass.x);

MyClass.printX();

类型的相等

类型守卫【ts做窄化】

class FileSystemObject { // 文件系统的对象

isFile(): this is FileRep { // 守卫:文件类型断言,触发类型窄化

return this instanceof FileRep;

}

isDirectory(): this is Directory {// 守卫:目录类型断言,触发类型窄化

return this instanceof Directory;

}

isNetworked(): this is Networked & this {// 守卫:域名类型断言,触发类型窄化

return this.networked;

}

constructor(public path: string, private networked: boolean) {}

}

class FileRep extends FileSystemObject {

constructor(path: string, public content: string) {

//super()相当于FileRep.prototype.constructor.call(this)

super(path, false)

}

}

class Directory extends FileSystemObject {

children: FileSystemObject[];

}

const fso: FileSystemObject = new FileRep("foo/bar.txt", "foo");

is(fso.isFile()) { // 文件

fso.content;

// const fso: FileRep

} else if (fso.isDirectory()) { // 目录

fso.children;

// const fsoL:Directory

} else if (fso.isNetworked()) { // 地址

fso.host;

// const fso:Networked & FileSysremObject

}

抽象类

如果抽象类中没有具体方法,全都是抽象方法,那就等价于interface接口

abstract class Base { // 抽象类 TS独有,JS中没有

// 抽象类不能实例化,只能继承

  abstract getName(): string;

  printName() {

    console.log("Hello," + this.getName());

  }

}

// 无法创建抽象类的实例

const b = new Base();

class Derived extends Base {

// 继承抽象类,要实现一下继承过来的抽象类中的抽象方法 abstract getName()

getName() {

return "world";

}

}

const d = new Derived();

d.printName();

TS的类型一致(所谓的子类可以赋值给父类)

class Point1 {

x = 0;

y = 0;

}

class Point2 {

x = 0;

y = 0;

}

// OK 对于typescript来说,相同的结构,就是同一类型,

// TS检查,发生在编译时,做静态类型检查,看的就是静态成员是否一致

const p : Point1 = new Point2();

class Person {

name: string;

age:number;

}

class Employee {

name: string;

age:number;

salary: number;

}

// OK TS是按成员来分辨是否是继承,像上面这种,TS认为是隐形的继承

// Employee比Person多一个成员,认为 class Employee extends Person {}

const p: Person = new Employee();

小结

TS如何判断类型的一致?代价如何?基于实际的每一项成员是否一致判断的。代价可以承担,就是慢点,而且发生在编译时。真正运行时,是不会有ts代码的,也不会帮我们生成新的代码不占我们的性能在Class的使用中,TS有实现JS没有的能力吗?没有,去掉ts部分依然可以运行,ts只有少量的是js没有的,如枚举

参考阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: