? TS面向对象
TypeScript的面向对象和ES6以后的语法其实差不太多
定义类
class 类名 {
属性名:类型;
constructor(参数:类型){
this.属性名 = 参数;
}
方法名(){
.....
}
}
示例:
class Person {
//构造器
constructor(name: string, age: number) {
//this指向创建时候的示例
this.name = name;
this.age = age
}
//普通属性
name: string;
age: number;
//只读属性,无法修改
readonly onyRead:number =123;
//静态属性
static money:number = 33333;
//方法
sing(){
console.log(this.name+" is singing");
}
}
//使用
let kano = new Person('kano',18);
kano.sing()
console.log(Person.money);
继承
继承在语法上和其他的面向对象语言没有什么太大差距,不过确实比较像Java
//Animal class Animal { name: string age: number
constructor(name: string, age: number) { this.name = name this.age = age } say() { console.log('Something say'); }
}
//Dog class Dog extends Animal { constructor(name: string, age: number) { //访问基类的构造器,传递参数 super(name, age) }
override say() { console.log('Dog Bark'); } //父类的say originalSay(){ super.say() } run(){ console.log(this.name+'is running') }
}
//cat class Cat extends Animal { constructor(name: string, age: number) { super(name, age) } //不写override默认重写父类方法 say() { console.log('cat miaomiao'); } }
抽象类
//Animal抽象类,禁止被作为实例 abstract class Animal { name: string age: number //抽象类中的方法是受保护的 protected constructor(name: string, age: number) { this.name = name this.age = age } //抽象方法 abstract say():void; }
//Dog //抽象类的内容必须全部实现 class Dog extends Animal { constructor(name: string, age: number) { super(name, age) } override say() { console.log('Dog Bark'); } }
//cat class Cat extends Animal { constructor(name: string, age: number) { super(name, age) } say() { console.log('cat miaomiao'); } }
接口
接口可以描述一个对象内属性的类型,相当于给派生对象一个规范
和TS的type差不多,不过也有区别:
-接口可以在定义类的时候去限制类的结构
-接口中的所有属性,都不能有实际的值,这一点和C#是一样的
//描述一个对象的类型 type myType = { name:string, age:number }
//接口用来定义一个类结构,规范 interface myInterface{ name:string, age:number } //同名接口可以合并 interface myInterface{ gender:string }
//实现接口 const obj:myInterface ={ name:'xxs', age:1, gender:'male' } //实现类型 const typeObj:myType={ name:'zs', age:11 }
定义类时,可以使类去实现接口(满足接口的要求)
和其他面向对象语言一样,TS的接口也是可以多继承的
//USB2.0规范 interface USB2 { type: string pins: number transferData(): void }
//USB3.0规范(老) interface USB3 { type: string transferData(): void }
class MyUSBCable implements USB3, USB2 { constructor(pins: number, type: string) { this.pins = pins this.type = type } pins: number; type: string; transferData(): void { if(this.pins <= 4){ console.log('lowSpeed type:' + this.type) }else{ console.log('hiSpeed type:'+this.type) } } }
const uselessCable = new MyUSBCable(4,"MicroUSB") uselessCable.transferData()
属性封装
TS也有类似get,set的访问修饰符,用来增强和约束对象中的属性
//定义一个表示人的类 class Person { // private _name: string; // private _age: number;
//getter与setter get name() { return this._name } set name(value) { this._name = value; } get age() { return this._age } set age(value) { if (value &gt; 0) { this._age = value } } //可以直接将属性定义在构造函数里面(感觉好绕,不建议这么写) constructor(private _name: string,private _age: number) { // this._name = name // this._age = age }
}
const p = new Person('nana', 18); //不规范赋值 p.age = -111; p.name = 'kano'
泛型
在定义函数或者是类的时候,如果遇到变量、返回值类型不明确的时候就可以使用泛型
//泛型
//T表示任意类型,名字随意
function fn<T>(a: T): T {
return a;
}
//可以直接调用具有泛型的函数
console.log(fn(10));//不指定泛型,TS会自动推断
//手动指定类型
console.log(fn<boolean>(false));//指定泛型,执行效率更高
泛型也可以有多参数
//多参数泛型
function fn2<T, K>(a: T, b: K): T {
console.log(a, b)
return a;
}
fn2<number, string>(123, 'kano')
泛型限定,下面的泛型只允许实现了IO接口的类/对象作为参数
interface IO { someNumber: string }
//限定泛型 //函数只接收实现了IO接口的类/对象 function fn3<T extends IO>(a: T): string { return a.someNumber }
// class cable implements IO{ // public someNumber:string // constructor(cable:string) { // this.someNumber = cable // } // }
//传一个实现IO接口的对象 // const usbCable = new cable('usbCable')
//传一个实现IO接口的类 console.log(class cable implements IO{ public someNumber:string constructor(cable:string) { this.someNumber = cable } });
除此之外,类也可以是泛型的
//泛型类
class cls<T>{
prop:T
constructor(props:T) {
this.prop = props
}
}
const obj = new cls<number>(123)
补充
使用接口描述一个数组:
interface Arr {
[index:number]: number
}
let arr:Arr = [1,3,4]
强制转换:
function fn(flag:boolean|number):boolean {
return !!flag
}
!!就表示强制转换