TS学习笔记(三):类

栏目: 后端 · 前端 · 发布时间: 5年前

内容简介:传统的 JavaScript 程序使用函数和基于原型的继承来创建可重用的组件,从 ES6 开始,JavaScript 程序能够使用基于类的面向对象的方式。使用 TypeScript,你可以使用 ES6 中规定的新特性,编译后的 JavaScript 可以在所有主流浏览器和平台上运行。在构造器里访问 this 的属性之前,一定要调用默认是 public, 不再赘述,参考前面例子。

传统的 JavaScript 程序使用函数和基于原型的继承来创建可重用的组件,从 ES6 开始,JavaScript 程序能够使用基于类的面向对象的方式。使用 TypeScript,你可以使用 ES6 中规定的新特性,编译后的 JavaScript 可以在所有主流浏览器和平台上运行。

基本用法

class Person {
  public love: string;
  constructor(love: string) {
    this.love = love;
  }
  public sayLove() {
    console.log(`my love is ${this.love}`)
  }
}

复制代码

继承

在构造器里访问 this 的属性之前,一定要调用 super() ,这个是 TypeScript 强制执行的一条重要规则。

class Person {
  public love: string;
  constructor(love: string) {
    this.love = love;
  }
  public sayLove() {
    console.log(`my love is ${this.love}`)
  }
}

class SuperPerson extends Person {
  public name: string;
  constructor(love: string, name: string) {
    super(love);
    this.name = name;
  }
  public sayName(){
    console.log(`my name is ${this.name}`)
  }
}

let me = new SuperPerson('HTML', 'funlee');
me.sayLove()
me.sayName()
复制代码

访问控制

public、private、protected

默认是 public, 不再赘述,参考前面例子。

当成员标记为 private 时,它就不能在声明它的类的外部访问,用 protected 修饰的属性依然如此。

class Person {
  private love: string; // or  prot
  constructor(love: string) {
    this.love = love;
  }
  public sayLove() {
    console.log(`my love is ${this.love}`)
  }
}

let me = new Person('TS');
me.love = 'JS'; // error

复制代码

private 和 protected 有一点不同, protected 成员在派生类中仍然可以访问。例如:

class Person {
  protected name: string; 
  constructor(name: string) {
    this.name = name;
  }
}
class Man extends Person {
  private love: string;
  constructor(name: string, love: string) {
    super(name);
    this.love = love;
  }
  public say() {
    // 如果Person 中用 private 修饰 name 则不能访问到 name 属性
    console.log(`my name is ${this.name}, and my love is ${this.love}`);
  }
}
let me = new Man('funlee', 'TS');

复制代码

注意:TypeScript 使用的是结构性类型系统,所以当比较两种不同的类型时,如果所有的成员的类型都是兼容的,那么这两个类型就是兼容的。如:

class A {
  prop1: string
}
class B {
  prop1: string
  prop2: string
}
let instance:A = new B() // 允许这么做,因为A的所有成员类型,B中都有

复制代码

但是如果被比较的类里面含有 private 和 protected 类型成员的时候,情况就不同了,这时候需要另一个类里也含有相应的 private 或 protected 成员,类型才能是兼容的,所以有:

class A {
  private prop1: string
}
class B {
  private prop2: string
}
let p1:A = new B() // 报错
class C extends A {

}
let p2:A = new C() // 允许这么做

复制代码

readonly

可以使用 readonly 关键字将属性设置为只读的,只读属性必须在声明时或构造函数里被初始化。

class Person {
  readonly name: string;
  constructor(name: string) {
    this.name = name;
  }
}
let me = new Person('funlee');
me.name = 'new name'; // error

复制代码

参数属性

参数属性允许同时 创建初始化成员 ,可以把声明和赋值合并至一处,如:

class Person {
  constructor(public name: string, protected love: string, readonly age: number, private weight: string) {
    this.name = name;
    this.love = love;
    this.age = age;
  }
  public sayWeight() {
    console.log(`my weight is ${this.weight}`)
  }
}
let me = new Person('funlee', 'TS', 18, '55kg');
me.sayWeight()

复制代码

存取器

TypeScript 支持 getter 和 setter,但是有一点限制:编译器输出必须设为 ES5 或者更高,不支持降级到 ES3,另外,当一个存取器只带有 get 却不带有 set 时,它会被自动推断为 readonly。

class Person {
  public _love: string;
  constructor(love: string) {
    this._love = love;
  }
  get love(): string{
    return this._love;
  }
  set love(newLove: string) {
    this._love = `error!! my love can't be chenged`;
  }
}
let me = new Person('TS');
console.log(me.love); // TS
me.love = 'HTML';
console.log(me.love); // error!! my love can't be chenged

复制代码

静态属性

可以使用static来定义类里的静态属性,静态属性属于类自身,而不属于实例,访问的时候要用类名访问,而不能用实例对象访问,如:

class Person {
  static love: string = 'TS';
}
let me = new Person();
console.log(Person.love); // TS
console.log(me.love); // error

复制代码

抽象类

抽象类只能作为其他派生类的基类使用,抽象类不能被实例化,它具有如下特点:

  • 抽象类可以包含成员的实现细节,且抽象类必须用 abstract 声明
  • 抽象类里不含方法体的方法称为抽象方法,使用 abstract 声明,抽象方法必须被子类实现(抽象方法必须使用 abstract 关键字声明,且可以包含访问修饰符)
abstract class Person {
  public love: string;
  constructor(love: string) {
    this.love = love;
  }
  abstract sayLove(): string; // 必须在派生类中实现
}
class Man extends Person{
  constructor(love: string){
    super(love)
  }
  sayLove() {
    return `my love is ${this.love}`;
  }
}
let me = new Man('TS');
console.log(me.sayLove()); // my love is TS

复制代码

把类当做接口使用

类定义会创建两个东西:类的实例类型和一个构造函数,因为类可以创建出类型,所以能够在允许使用接口的地方使用类。

class Person {
  name: string;
  age: number;
}
interface Man extends Person {
  love: string;
}
let me: Man = {
  name: 'funlee',
  age: 18,
  love: 'TS'
}

复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序员的数学3

程序员的数学3

[日] 平冈和幸、[日] 堀玄 / 卢晓南 / 人民邮电出版社 / 2016-3 / 79.00元

本书沿袭“程序员的数学”系列平易近人的风格,用通俗的语言和具象的图表深入讲解了编程中所需的线性代数知识。内容包括向量、矩阵、行列式、秩、逆矩阵、线性方程、LU分解、特征值、对角化、Jordan标准型、特征值算法等。一起来看看 《程序员的数学3》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具