iconhot 2020-05-26
解决,类,接口,方法的复用性,以及对不特定数据类型的支持
如果需要一个函数传入类型必须返回类型,同时满足,泛型可以解决。any类型放弃了类型检查。
function getData(value:any):any{ return ‘hahaha‘; // 修改了返回值 }
泛型:可以支持不特定的数据类型,要求传入的参数和返回的参数一致
// T表示泛型,具体什么类型时调用这个方法的时候决定的 function getData<T>(value:T):T{ return value; } getData<number>(123); //调用的时候尖括弧种写什么类型,传参些什么类型 getData<string>(123); // 报错 // 函数的返回值可以实any function getData<T>(value:T):any{ return ‘123123‘; } getData<number>(123); // √ getData<string>(‘123‘);// √
eg:有一个最小堆算法,需要同时支持返回数字和字符串两种类型
class MinClass{ public list:number[] = []; add(num:number) { this.list.push(num); } min():number{ var minNum = this.list[0]; for(let i = 0;i < this.length;i++) { if(minNum>this.list[i]) { minNum = this.list[i]; } } return minNum; } } let m = new MinClass(); m.add(23); m.add(1); m.add(0); m.add(45); m.min();// 0
泛型类:
class MinClass<T>{ public list:T[] = []; add(num:T):void { this.list.push(num); } min():T{ var minNum = this.list[0]; for(let i = 0;i < this.length;i++) { if(minNum>this.list[i]) { minNum = this.list[i]; } } return minNum; } } var m = new MinClass<number>();// ()表示实例化类,并且制定了类的T代表的类型式number m.add(1); m.add(3); m.add(8); m.min(); // 1.可以传入任意类型 // 2.可以类型校验 var m1 = new MinClass<string>();// ()表示实例化类,并且制定了类的T代表的类型式number m1.add(‘a‘); m1.add(‘d‘); m1.add(‘g‘); m1.min();
// 定义一个函数接口 interface Config{ (value1:string,value2:string):string; } let setData:Config=function(value1:string,value2:string) { return value1+value2; } setData(‘name‘,‘zhangsan‘); // 改造接口泛型 // 方法1 interface Config{ <T>(value:T):T; } let setData:Config=function(value:T):T { return value; } setData<string>(‘name‘); setData<number>(123); // 方法2 interface Config<T>{ (value:T):T; } function getData<T>(value:T):T{ return value; } var myGetData:config<string> = getData; myGetData(‘123‘); // √
eg:定义一个user的类,主要共功能映射数据可字段然后定义一个MysqlDb的类这个类用于操作数据库然后把User类作为参数传入到MysqlDb中
class User{ username:string | undefined; password:string | undefined; } class MysqlDb{ add(user:User):boolean { // 通过User类检查add方法传入的参数 console.log(user); // {username:‘seafwg‘,passwrd:‘123456‘} return true; } } let u = new User(); u.username = ‘seafwg‘; u.password = ‘123456‘; let Db = new MysqlDb(); Db.add(u); // 改造: class User{ // User类不变 usenrame:string | undefined; password:string | undefined; } class MysqlDb<T>{ add(info:T):boolean{ console.log(info); return true; } } var u = new User(); u.username = ‘seafwg‘; u.password = ‘123456‘; var Db = new MysqlDb<User>(); // 把User类传入进行类型检查 Db.add(u); // 增加一个articleCate类和数据库进行映射 class ArticleCate{ title:string | undefined; desc:string | undefined; status:number | undefined; constructor(params:{ title:string | undefined, desc:string | undefined, status?:number | undefined }) { this.title = params.title; this.desc = params.desc; this.status = params.status; } } let a = new ArticleCate({ title:‘中国‘, desc: ‘国内新闻‘, status: 1 }); // 把ArticleCate类当作参数的泛型接口 let Db = new MysqlDb<ArticleCate>(); Db.add(a); // User?{username: "seafwg", password: "123456"} // ArticleCate?{title: "中国", desc: "国内新闻", status: 1}
eg:定义一个操作数据库的库,支持Mysql,MsSql,MongoDb
要求:Mysql,MsSql,MongDb功能一样,都有add,update,delete,get方法
注意:约束统一的规范,以及代码重用
解决方案:要约束规范所以要定义接口,需要代码重用所以要用到泛型
1.接口:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范
2.泛型:就是解决类,接口,方法的复用性
// 定义接口 interface DBInter<T>{ add(info:T):boolean; // 增加的时候不知道是什么类型,用泛型去检查,返回是否成功 update(info:T,id:number):boolean; delete(id:number):boolean; get(id:number):any[]; } // 定义一个操作mysql数据库的类 // 【注意:】要实现泛型接口,这个类也是一个泛型 // MysqlDb数据库的实现: class MysqlDb1<T> implements DBInter<T> { add(info: T): boolean { console.log(‘MysqlDb1 info‘, info) return true; // throw new Error("Method not implemented."); } update(info: T, id: number): boolean { throw new Error("Method not implemented."); } delete(id: number): boolean { throw new Error("Method not implemented."); } get(id: number): any[] { throw new Error("Method not implemented."); } } class User1{ username:string | undefined; password:string | undefined; } let us = new User1(); us.password = ‘123123‘; us.username = ‘seafwg‘; // 用户信息存储到MysqlDb1中 let oMysql = new MysqlDb1<User1>(); oMysql.add(us); // {password: "123123", username: "seafwg"} // MsSql数据库的实现 class MsSql<T> implements DBInter<T> { add(info: T): boolean { console.log(‘MsSql info‘, info) return true; } update(info: T, id: number): boolean { throw new Error("Method not implemented."); } delete(id: number): boolean { throw new Error("Method not implemented."); } get(id: number): any[] { throw new Error("Method not implemented."); } } // 用户信息存储到MsSql中 let oMssql = new MsSql<User1>(); oMssql.add(us);