多态
父类定义一个方法不去实现,让继承它的子类去实现,每一个子类有不同的表现。
class Animal {
name:string
constructor(name:string){
this.name = name
}
getVariety(){} //父类定义了getVariety方法不去实现
}
class Cat extends Animal{
constructor(name:string){
super(name)
}
getVariety():string{
return `${this.name}是只猫!` //子类Cat对getVariety的实现
}
}
class Dog extends Animal{
constructor(name:string){
super(name)
}
getVariety():string{
return `${this.name}是只狗!` //子类Dog对getVariety的实现
}
}
//这种子类继承父类后重写了getVariety方法,每个子类有自己不同的实现,叫多态
抽象类和抽象方法
TS中的抽象类是提供其他类继承的基类,不能直接实例化。用abstract关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。
抽象类和抽象方法用来定义标准,来约束子类必须实现指定方法
abstract class Animal {
name:string
constructor(name:string){
this.name = name
}
abstract getVariety():any
run():void{} //没有abstract标识的方法在子类中可以不实现
}
// const animal = new Animal() //报错!!抽象类无法实例化
class Dog extends Animal{
constructor(name:string){
super(name)
}
getVariety(){ //实现抽象方法中的getVariety方法,如果没有则报错!如果要标明返回值类型,必须和抽象方法中一致
return `${this.name}是只狗!`
}
}
const dog = new Dog('旺财')
console.log(dog.getVariety()) //旺财是只狗!
TS中的接口
在OOP中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用,接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部装药数据,也不关系这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法就可以满足实际需要。
使用interface关键字来定义:
属性类型接口
interface AnimalInfo{ //对传入对象的约束
name:string
age:number
sex?:boolean
}
function Dog(info:AnimalInfo) { //info使用定义好的约束,要求传进来的info必须满足AnimalInfo约定好的条件
console.log(`${info.name},${info.age}岁!`)
}
Dog({name:'mimi', age:2}) //不报错
Dog({name:'mimi'}) //报错
函数类型接口
//函数类型接口:对方法传入的参数以及返回值进行约束
interface encrypt {
(key:string,value:string):string //对函数进行约束
}
var md5:encrypt = function (key:string, value:string):string {
return key + value
}
md5('我是key', '我是value') //我是key我是value
md5('我是key') //报错
可索引接口
//可索引接口:对数组、对象进行约束
interface userArry { //对数组约束
[index:number]:string
}
const arr:userArry = ['111122', '23333']
const arr:userArry = [123, '23333'] //报错
interface userObj { //对对象进行约束
[index:string]:string //如果[index:string]:any,不管是Object或者是Arry都不会报错
}
const obj:userObj = ['22','333'] //报错
const obj:userObj = {a: '22', b: '333'} //不报错
类类型接口
interface Animal { //定义类类型接口
name:string
getVariety():string
}
class Dog implements Animal{ //对Dog类添加约束,使用implements关键字,Dog中必须有name属性和getVariety方法
name:string
constructor(name:string){
this.name = name
}
getVariety(): string {
return `${this.name}是只狗!`
}
}
const dog = new Dog('旺财')
类类型接口和前面的抽象类相似,都是要求子类按照约定好的标准去具体实现。
接口的扩展
interface Dog extends Animal{
say():void
}
class NorthDog {
unClod():void{
console.log('北极狗不怕冷!')
}
}
class Husky extends NorthDog implements Dog{ //继承+接口
name:string
constructor(name){
super()
this.name = name
}
getVariety(): string {
return `${this.name}是只狗!`
}
say(): void {
console.log('汪汪!!!')
}
}
const husky = new Husky('二哈')
husky.unClod()
泛型
泛型是解决类、接口、方法的复用以及对不特定数据类型的支持。
泛型可以支持不特定数据类型,要求传入参数和返回的参数一致。
function getDate<T>(value:T):T { //T由调用这个方法的时候决定
return value
}
getDate<number>(123) //正确
getDate<string>(123) //要求传入string 报错
泛型在class中的使用
class List<T>{
list:T[]
constructor(...list:T[]){
this.list = list
}
add(item:T):void{
this.list.push(item)
}
getList():T[]{
return this.list
}
}
const numList = new List<number>(1,2,3)
const stringList = new List<string>()
numList.add(8) //正确
stringList.add('a') //正确
console.log(numList.getList()) // [ 1, 2, 3, 8 ]
console.log(stringList.getList()) // [ 'a' ]
numList.add('a') //报错
stringList.add(1) //报错
泛型接口
interface Config<T> { //定义泛型接口
name:T
getName():T
}
class Dog<T> implements Config<T>{ //定义泛型类
name:T
constructor(name:T){
this.name = name
}
getName(): T {
return this.name
}
}
const dog = new Dog<string>('旺财!')
console.log(dog.getName())
const dog = new Dog<string>(11) //报错!