- TypeScript类的基本使用(修饰符)
- TypeScript类的抽象类(abstract)
- TypeScript类的高级技巧
一、TypeScript类的基本使用(修饰符)
TypeScript的类与ES6的类非常类是,所以建议先了解ES6的类的相关内容:ES6入门六:class的基本语法、继承、私有与静态属性、修饰器。
1.最简单的TypeScript的类示例与ES6实现对比:
1 class tsClass{ 2 public a:string ; //公有成员 3 private b:number[] ; //私有成员 4 protected c:string[] ; //被保护的成员 5 static e:string = 'e'; //静态属性 6 constructor(astr:string,barr:number[],carr:string[]){ 7 this.a = astr; 8 this.b = barr; 9 this.c = carr; 10 } 11 } 12 class SublevelCla extends tsClass { 13 private dname: string; //私有成员 14 constructor (astr:string,barr:number[],carr:string[],dname:string){ 15 super(astr,barr,carr);//继承tsClass构造字段 16 this.dname = dname;//sublevelCla自身构造字段 17 } 18 fun():void{ 19 console.log(tsClass.e);//通过类获取静态成员 20 } 21 } 22 23 let sub = new SublevelCla('a',[1,2,3],['a','b','c'],'sublevelName'); 24 sub.fun(); 25 console.log(sub.a); 26 // console.log(sub.b); //报错:私有成员不能被外部访问 27 // console.log(sub.c); //报错:被保护的成员不能被外部访问 28 // console.log(sub.dname); //报错:私有成员不能被外部访问
Ts类与Js类的修饰符对比:
Ts有公共成员(public)修饰符;Js没有该修饰符,但可以在构造函数constructor内直接使用this定义公共成员,用于生成每个实例对象的属性。
Ts有私有成员(private)修饰符;Js的私有成员修饰符是(#),该成员只能在当前类中使用,TS与JS没有区别。
Ts有受保护成员(protected)修饰符;Js没有该修饰符,也没有对应的成员语法。在Ts中受保护成员可以被字类访问在子类中使用,但不能被实例对象在外部访问。
Ts有静态成员(static)修饰符;Js中也有同样的修饰符,该成员最终被解析到类的自身属性上(解析成ES5的话就是函数的属性),静态属性可以被类名直接在任何地方引用。
Ts有只读成员(readonly)修饰符;Js中没有该修饰符,但是可以通过属性访问器get来实现。
1 //js示例代码 2 class jsClass{ 3 #b ; 4 #c ; 5 static e = 'e'; 6 constructor(astr,barr,carr,){ 7 this.a = astr; 8 this.#b = barr; 9 this.#c = carr; 10 } 11 } 12 13 class jsSubc extends jsClass{ 14 constructor(astr,barr,carr,dname){ 15 super(astr,barr,carr); 16 this.dname = dname; 17 } 18 fun(){ 19 console.log(jsClass.e); 20 } 21 } 22 let jsub = new jsSubc('a',[1,2,3],['a','b','c'],'sublevelName'); 23 jsub.fun(); 24 console.log(jsub.a); 25 // console.log(jsub.b);//undefined
关于类的继承在Ts和Js中都是使用extends关键字,并且在构造函数中使用super方法实现构造继承,这个方法都必须写在字类构造函数内的最前面。
Ts受保护的成员的使用方式就是通过添加到父类构造函数,然后字类构造继承该成员,在子类中就能使用this关键字访问该成员了,子类中不需要再在自生声明该成员了。
1 //这个官方示例完美的展示了受保护成员的应用 2 class Person { 3 protected name: string; 4 constructor(name: string) { this.name = name; } 5 } 6 7 class Employee extends Person { 8 private department: string; 9 10 constructor(name: string, department: string) { 11 super(name) 12 this.department = department; 13 } 14 15 public getElevatorPitch() { 16 return `Hello, my name is ${this.name} and I work in ${this.department}.`; 17 } 18 } 19 20 let howard = new Employee("Howard", "Sales"); 21 console.log(howard.getElevatorPitch()); 22 console.log(howard.name); // 错误
Ts只读成员示例在官方文档中也有非常好的示例,这里直接复制展示该示例:
1 class Octopus { 2 readonly name: string; 3 readonly numberOfLegs: number = 8; 4 constructor (theName: string) { 5 this.name = theName; 6 } 7 } 8 let dad = new Octopus("Man with the 8 strong legs"); 9 dad.name = "Man with the 3-piece suit"; // 错误! name 是只读的.
同样Ts中也可以使用set与get作为存取器,通过属性访问器setter和getter实现的成员相当于定义了一个(public)公有成员,每个实例都会产生自己的实例属性,唯一的区别就是在不写入值时会读取类中定义的私有属性值,这个特性与JS完全一致。常见的使用访问器实现读写私有属性(一般只写):
1 class Person{ 2 private _name: string = 'person'; 3 //给私有属性赋值 4 set setName(val:string){ 5 this._name = val; 6 } 7 //读取私有属性值(一般不建议使用) 8 get getName(){ 9 return this._name; 10 } 11 } 12 var obj1 = new Person(); 13 var obj2 = new Person(); 14 obj1.setName = 'obj1'; 15 console.log(obj2.getName);//person 16 console.log(obj1.getName);//obj1
1 //js 2 class Person{ 3 #name = 'person'; 4 //给私有属性赋值 5 set setName(val){ 6 this.#name = val; 7 } 8 //读取私有属性值(一般不建议使用) 9 get getName(){ 10 return this.#name; 11 } 12 } 13 var obj1 = new Person(); 14 var obj2 = new Person(); 15 obj1.setName = 'obj1'; 16 console.log(obj2.getName);//person 17 console.log(obj1.getName);//obj1