泛型
泛型是一种参数化数据类型,具有以下特点
1:定义时不明确,使用时必须明确成 某种具体数据类型 的数据类型【泛型的宽泛】
2:编译期间进行 数据类型安全检查 的数据类型【泛型的严谨】
泛型类的格式: class 类名<泛型形参类型>{ }
class ArrayList<T>{
array: Array<T>
add(data:T){
....
}
....
}
泛型形参类型一般有两种表示:
1、 A-Z 任何一个字母(绝大多数情况是这种)
2、 语义化的单词来表示
class ArrayList<T> {
public element: Array<T>;
constructor() {
this.element = [];
}
public index: number = 0;
public add(ele: T) {
this.element[this.index++] = ele;
}
get(index: number): T {
return this.element[index];
}
}
type stuType = { stuname: string; age: number; address: string };
let stuOne: stuType = { stuname: "wnagwu", age: 23, address: "beijing" };
let stuTwo: stuType = { stuname: "lisi", age: 39, address: "shanghai" };
let stuThree: stuType = { stuname: "liuqi", age: 31, address: "nanjing" };
let arrayList3 = new ArrayList<stuType>();
arrayList3.add(stuOne);
arrayList3.add(stuTwo);
arrayList3.add(stuThree);
let stuobj = arrayList3.get(1);
console.log(stuobj.stuname); //能点出来
//泛型如果在使用时没有具体化的类型,那么就会默认为unknown数据类型
//class ArrayList<T=any> {} //这样默认值就是any
//class ArrayList<T=number> {}
//这样默认值就是number,但下面的arrayList5.add("abc")就会报错
let arrayList5 = new ArrayList();
arrayList5.add(3);
arrayList5.add("abc");
arrayList5.add(stuOne);
arrayList5.get(2); //点不出来,类型“unknown”
泛型约束
泛型约束简单点说就是把泛型的具体化数据类型范围缩小
T extends object
表示具体化的泛型类型只能是 object 类型
泛型接口+ 泛型类 + 泛型约束 + 多态
//泛型接口 + 泛型类
interface List<T> {
add(ele: T): void;
get(index: number): T;
size(): number;
}
class ArrayList<T> implements List<T> {
public array: Array<T>;
public index: number = 0;
constructor() {
this.array = [];
}
public add(ele: T) {
this.array[this.index++] = ele;
}
size() {
return this.index ? this.index : 0;
}
get(index: number): T {
return this.array[index];
}
}
// 定义继承类(多态)
abstract class People {
public name!: string;
public abstract info(): void;
public eat() {
console.log("人类-吃饭");
}
}
class Man extends People {
public info() {
console.log("男人");
}
}
class Woman extends People {
public info() {
console.log("女人");
}
}
// 结合使用
class Tcs {
//泛型约束
public rent<T extends object>(list: List<T>) {
for (let i = 0; i < list.size(); i++) {
let res = list.get(i);
console.log("get拿到的类型是:", res);
//虽然传入前和get拿到的类型是一样的,外部可以点操作,这里不行。
//是因为谁知道你传入的泛型类是否一定有info()函数,所以需as断言后才能使用点
//或者泛型约束为People类型
(res as any).info(); //用了any自然不能点操作
}
}
}
//let aList: List<String> = new ArrayList<String>();
//泛型约束是为了防止,如上句,泛型为String则会影响Tcs类的内部代码使用
let aList: List<People> = new ArrayList<People>();
//上句:左边是List接口,右边是ArratList接口。同样是多态,接口的多态
let bus: People = new Woman(); //类的多态
console.log("传入前的类型是:", bus);
aList.add(bus);
aList.add(new Man()); //类的多态
let tc = new Tcs();
tc.rent(aList);
export {};
泛型函数:
格式: 函数名<泛型1,泛型2> (参数中可以使用泛型类型):返回值也可以是泛型类型
泛型函数好处:可在调用返回后 得到返回值的具体数据类型,从而有点操作和类型错误的提示
let numArr: number[] = [1, 3, 5, 7];
let strArr: Array<string> = ["a", "c", "e", "g"];
// Array<T> 等于 T[]
function funa<T>(arr: Array<T>): T[] {
let newNumArr: Array<T> = [];
newNumArr.push(arr[0]);
return newNumArr;
}
console.log("funa1:", funa(numArr)); // [ 1 ]
console.log("funa2:", funa(strArr)); // [ 'a' ]
泛型函数+重载
function funb(data: string): string;
function funb<T>(data: T): T;
function funb(data: any): any {
if (typeof data === "string") {
return "字符串类型";
}
if (data instanceof Array) {
return funa(data);
}
}
console.log("funb1:", funb("abcde")); // 字符串类型
console.log("funb2:", funb(numArr)); // [ 1 ]
网友评论