ts除了实现所有ES6中的类功能外,还添加了一些新的方法
类(class)相关概念
- 类(class):对事物的抽象,包含属性和方法
- 对象(Object):类的实例,通过
new生成 面向对象的三大特性:封装、继承、多态
- 封装(Encapsulation):将对数据操作细节隐藏,只暴露对外接口。只能通过暴露的接口来访问对象,而不能任意更改对象内部的数据
- 继承(Inheritance):子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
- 多态(Polymorphism):有了继承才有多态,在调用类实例方法的时候,尽量把变量视作父类类型,这样,所有子类类型都可以正常被接收
- setter或getter:用来改变属性的读取和赋值行为
- 修饰符:修饰符是一些关键字,用于限定成员或类的性质,如
public表示公有属性或方法 - 抽象类(Abstract Class):抽象类是供其他类继承的基类,抽象类不允许被实例化。抽象类中的抽象方法必须在子类中被实现。
- 接口(Interfaces):不同类之间公有的属性或方法,可以抽象为一个接口。接口可以被类实现(implements)。一个类只能继承自另一个类,但可以实现多个接口。
ES6+中类的用法
// 属性和方法class Animal {constructor(name) {this.name = name}sayHi() {return `My name is ${this.name}`}}// 类的继承class Cat extends Animal {constructor(name) {super(name) // 调用父类的 constructor(name)console.log(this.name)}sayHi() {return `Cat, ` + super.sayHi() // 调用父类的sayHi}}let c = new Cat('Miao') // Miaoconsole.log(c.sayHi()) // Cat, My name is Miao// setter 和 getterclass Animal {constructor(name) {this.name = name}get name() {reutrn 'Jack'}set name(value) {console.log('setter: ' + value)}}let a = new Animal('kitty'); // setter: Kittya.name = 'TT' // setter: TTconsole.log(a.name) // Jack// 静态方法:可以通过类名直接调用的方法class Animal {static isAnimal(a) {return a instanceof Animal}}let a = new Animal('jack')Animal.isAnimal(a) //truea.isAnimal(a) // Error: a.isAnimal is not a function// 实例属性class Animal {name = 'Jack' // 实例可以直接调用constructor() {}}let a = new Animal()console.log(a.name) // Jack// 静态属性,类可以直接调用的属性class Animal {static num = 42constructor() {}}console.log(Animal.num) // 42
TypeScript中类的用法
修饰符、抽象类等
访问修饰符public、private、protected
TypeScript 可以使用三种访问修饰符,分别是:public,private, protected
- public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是public的
- private 修饰的属性或方法是私有的,不能在声明它的类的外部使用,包括子类
- protected 修饰符是受保护的,和private类似,区别是它在子类中是允许被访问的。
private、protected属性示例
// 示例1class Animal {public name;public constructor(name) {this.name = name}}let a = new Animal('Jack')console.log(a.name) // Jacka.name = 'Tom'console.log(a.name) // Tom// 示例2class Animal {private name;// protected name;public constructor(name) {this.name = name}get getName() {return this.name}}class Cat extends Animal {constructor(name) {super(name)console.log('cat', name)}get catName() {return this.name}}let a = new Animal('Jack')console.log(a.getName) // Jackconsole.log(a.name) // Errora.name = 'Tom' // Error// Property 'name' is private and only accessible within class 'Animal'.let ce = new Cat('xx')console.log(ce.name) // Error 不管是protected还是privateconsole.log(ce.catName) // protected name 则ok,private name 则Error
private、protected用来修饰构造函数
当构造函数修饰为 private 时,该类不允许被继承或者实例化
class Animal {public name;private constructor (name) {this.name = name;}}class Cat extends Animal { // Error 继承constructor (name) {super(name);}}let a = new Animal('Jack'); // Error 实例化
当构造函数修饰为 protected 时,该类只允许被继承
class Animal {public name;protected constructor (name) {this.name = name;}}class Cat extends Animal { // OKconstructor (name) {super(name);}}let a = new Animal('Jack'); // Error
在构造函数参数中使用修饰符
等同于类中定义该属性,使代码更简洁
class Animal {// public name: string;public constructor (public name) {this.name = name;}}
只读属性关键字readonly
class Animal {readonly name;public constructor(name) {this.name = name;}}let a = new Animal('Jack');console.log(a.name); // Jacka.name = 'Tom'; // Error
如果readonly和其他访问修饰符一起使用,需要写在其后面。
class Animal {// public readonly name;public constructor(public readonly name) {this.name = name;}}
抽象类(abstract)
abstract 用于定义抽象类和其中的抽象方法
抽象类是不允许被实例化的
abstract class Animal { // 抽象类public name;public constructor(name) {this.name = name;}public abstract sayHi(); // 抽象方法}let a = new Animal('Jack'); // Error 不允许被实例化
抽象类中的抽象方法必须被子类实现
abstract class Animal {public name;public constructor(name) {this.name = name;}public abstract sayHi();}class Cat extends Animal { // Error,子类没有实现抽象方法public eat() {console.log(`${this.name} is eating.`);}}let cat = new Cat('Tom');
正确示例
注意 TypeScript的编译结果中,仍然存在这个抽象类
abstract class Animal {public name;public constructor(name) {this.name = name;}public abstract sayHi();}class Cat extends Animal {public sayHi() {console.log(`Meow, My name is ${this.name}`);}}let cat = new Cat('Tom');
类类型
class Animal {name: string;constructor(name: string) {this.name = name}sayHi(): string {return `My name is ${this.name}`}}let a: Animal = new Animal('Jack');console.log(a.sayHi()) // My name is Jack
