// ts3接口interface
// 抽象类一般是用来封装一些功能的方法的 抽象一些给子类方法 不能用new实力化
export {}
abstract class Animal1 {
name:string;
abstract speak():void;// 返回值是void
}
// 接口中的方法都是抽象的
interface Flying{
fly():void
}
interface Eating{
eat():void
}
class Cat extends Animal1 implements Flying,Eating{
speak(){
console.log('喵喵喵!')
//重写父类的方法
}
// 继承一个接口 实现它的方法
fly(){
console.log('我是一只飞猫')
}
eat(){
console.log('我是一只猫')
}
}
let a1= new Animal1();// 无法new
let cat = new Cat();
cat.speak()
// 重写和重载
// 重写是子类重写父类的方法
// 重载是对一个函数实现多种定义
// 继承 和多态(狗和猫叫)
// interface
// 接口表示对象的形状
interface Speakable{
speak():void;
name:string
}
let speaker:Speakable = {
name:'guozimo',
speak(){
}
}
// 描述对象
interface Rectangle{
width:number
height:number
}
let r1:Rectangle= {
width:10,height:20
}
// 描述行为的抽象
interface AnimalLike{
eat():void;
move():void
}
interface PersonLike extends AnimalLike{
speak():void
}
class Girl implements AnimalLike{
eat(){
}
move(){
}
speak(){
}
}
//接口可以继承
// 规定一个变量对应的接口类型 必须有id和name 其他属性任意 不管
interface Person{
readonly id:number;// 只读属性
name:string;// 必填属性
[propName:string]:any// 增加任意属性都可以
}
let p2:Person={
id:1,
name:'guozimo',
age:10,
home:'北京'// 属性多少个不确定 所以定义不能写死
}
p2.id// 会报错 只读属性
// 如何用接口规范 定义函数
interface DiscountInterface{
(price:number):number
// 第二个number是返回值规定
}
let discount:DiscountInterface = function(price:number):number{
return price*0.8;
}
interface sumInterface{
(...args:any[]):number
}
let sum3:sumInterface = function():number{
let args:IArguments = arguments
return Array.prototype.slice.call(args).reduce((val,item)=>val+item,0)
}
let sum4:sumInterface = (...args:number[])=>{
return args.reduce((val,item)=>val+item,0)
}
///...args剩余参数用法
//剩余参数语法允许我们将一个不定数量的参数表示为一个数组。
// 可索引 接口 对数组或者对象进行约束
interface UserInterface{
[index:number]:string
}
let arr:UserInterface=['index':'guozimo']
console.log(arr)
interface UserInterface2{
[index:string]:string
}
let obj2: UserInterface2 = {name:'guozimo'}
// 类的接口
// 用接口约束构造函数的类型
class Animal3{
// constructor(public name:string){
// 有public的化 就这一行代码就行了 如果没有就需要用下面的方式
// }
// 或者用下面的方式
name:string;
constructor(name:string){
this.name=name
}
static age:number;
static getAge(){
console.log(this.age)
}
}
class Desk{
constructor(public price:number){
}
}
let a3 = new Animal3('guozimo')
console.log(a3)
interface withNameClass{
new(name:string):Animal3// 类的构造函数 是类的属性
age:number// 都是类的属性
getAge():void// 类的属性
// 构造函数的返回类型是animal3
}
function createClass(clazz:withNameClass,name:string){
return new clazz(name);
}
// 创造类
let a4 =createClass(Animal3,'guozimo')
console.log(a4)
let a5 =createClass(Desk,'jiagou')// 类型interface定义了 所以desk 不行
console.log(a5)// 会报错 类型不一致
// 泛型
// 使用的时候指定类型 也就是说可以取代any 的 根据传入决定参数 T 是一种number string 等的类型
function createArray<T>(length:number,value:T):T[]{
let arr:T[] = []
for(let i=0;i<length;i++){
arr[i]=value
}
return arr
}
let arr2 = createArray<number>(3,8)
let arr3 = createArray<string>(3,'8')
// 泛型赋值
// 不确定第二个参数 是什么类型的
// 调用的时候才知道是什么类型的
console.log(arr)