公司免费网站搭建多用户建站平台
目录
泛型的概念
接口是对方面的描述(Aspect),继承其中几个方法。重定义方法
泛型是对共性的提取
泛型(Generics)
泛型的例子
泛型类
推荐写法
泛型约束
keyof操作符
泛型的特化(实例化)
小结
泛型的概念
- 对比这3个概念,思考他们的区别:
- interface(接口)
- Car is runnable
- Extend(继承)
- Car is machine
- Generics(泛型)
- Runnable
- interface(接口)
// 接口写法
interface Runnable { // 接口run() : number
}
interface Repairable {repaire(): void
}
class Car implements Runnable, Repairable {run() : number {return 1 }repaire(){return }
}
// 继承写法;不是首选,因为它的祖类可能功能太多了,不一定适应子类
class XXXCar extends Car {run() : number {return 1 }repaire(){return }
}
接口是对方面的描述(Aspect),继承其中几个方法。重定义方法
- 小孩可以长大
- 小孩是Growable
- 动物可以进化
- 人是Evolvable
泛型是对共性的提取
- 木头可以做桌子
- 木头是:DeskMakable?
- 木头还可以:burn/wash/play...(耦合)
- 泛型的表达
- DeskMaker<Wood>
- DeslMaler<Iron>
interface Material {getHardness(): number;
}
class DeskMake <T extends Material> { // 做桌子的泛型material : T // 材料make() {const hardness = this.material.getHardness() }
}
// 泛型的解耦
const maker = new DeskMaker<Wood>()// 做木头桌子
const maker = new DeskMaker<Iron>()// 做铁桌子
泛型(Generics)
- 对共性的抽象
- 将类型作为参数
- 更好的分离关注点
泛型的例子
// 一个identity函数是自己返回自己的函数
// 当然可以声明它是:number =>number
function identity(arg:number): number {return arg;
}
// 为了让identity支持更多类型可以声明它是any
function identity(arg:any):any {return arg;
}
// any会丢失后续的所有检查,因此可以考虑用泛型
function identity<Type>(arg:Type): Type {return arg;
}
let output = identity<string>("MyString")
// 不用显示的指定<>中的类型
// let output = identity("MyString")
output = 100 // Error
泛型类
class GenericNumber<NumType> {zeroValue: NumType;add: (x: NumType, y : NumType) => NumType;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
// (number, number) -> number
myGenericNumber.add = function (x,y) {return x + y;
}
let stringNumeric = new GenericNumber<string>();
stringNumeric.zeroValue = "";
stringNumeric.add = function (x,y){return x + y;
}
推荐写法
class GenericNumber<T> {zeroValue: Tconstructor(v:T) { // 构造器this.zeroValue = v }add(x:T,y:T) {return x + y }
}
泛型约束
type lengthwise = {length: number
}
interface lengthwise {length: number
}
function loggingIdentity<Type extends {length: number
}>(arg: Type): Type {console.log(arg.length);return arg
}
keyof操作符
type Point = { x:number; y: number };
type P = keyof Point;
// P = "x" | "y"
function foo(x: keyof Point) {}
泛型的特化(实例化)
function create<Type>(c: { new(): Type }): Type {return new c();
}
create(Array) // Array的实例 => new Array()
create(Array<string>)// Error,不能完全替代实例化函数
小结
- 泛型解决了什么问题?解决了在我们做程序设计的时候,对于很多共性的抽象的问题,同时也解决了很多共性问题类型设计不够严格的问题。
- 什么时候用接口?什么时候用泛型?当你想约束一个类型,它有哪些成分的时候用接口,当你想提取一类东西共性的时候我们用泛型
- 下面方法是否成立?不成立
function add<T>(a:T,b:T){return a + b
}