A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 AreYouGlad 于 2017-12-20 11:53 编辑



接口

  • 接口就是契约, 可用来限定对象应该由哪些属性或方法构成
  • 定义接口需要使用interface关键字

作用
  • 在编写大型项目时, 我们可能需要先设计一下这个项目的构成, 比如需要那些模块, 实现那些类, 每个类有那些功能
  • 那么在设计的过程中我们可以使用代码进行记录与描述, 这些简单的代码就是接口
  • 接口不会实现任何具体的业务逻辑, 它的作用就是用来规范或提醒将来如何实现
  • 使用接口还有很多好处, 比如下面这个人使用接口后的评价

语法与特性
[AppleScript] 纯文本查看 复制代码
interface Person {
        name: string;
        age: number;
        gender: string = '男';              // 报错, 接口里的属性不能赋值
        say(): void;
        study(): void;
        run(): void{ console.log('跑') }  // 报错, 接口里的方法不能实现
}

使用范例

用接口约束类
  • 我们先使用interface设计一个接口, 里面描述某种类应该有的属性与方法, 然后我们再根据接口去实现对应的类
  • 同时为了让工具能够自动帮我们分析实现的对不对,有没有缺失, 可以在类上使用implements关键接口

[AppleScript] 纯文本查看 复制代码
// 使用接口定义Person类应该有的属性与方法
interface PersonInterface {
  name: string;
  age: number;
  eat(food: string): void;
}

// 当真正编写Person类时, 使用implements关联对应的接口, 以约束我们的实现
class CNPerson implements PersonInterface {

                // 如果不添加name或age就会报错, 多添加不会报错
    constructor(public name: string, public age: number, public gender: string) {}

    // 不实现这个方法就会报错
    eat(food: string): void {
            console.log('我要吃${food}');
    }

    // 多实现不会报错
    say(): void {
            console.log(`我是${this.name}`);
    }
}

用接口约束字面量对象
  • 我们在定义变量时, 如果想限制这个变量可存储的对象具体结构, 那么变量的类型可以为某个接口的名称
  • 注意: 接口类型的变量, 必须严格按照接口的定义数据结构进行赋值,多了少了都不行

[AppleScript] 纯文本查看 复制代码
interface data {
        a: number,
        b: string
};

let obj: data = { a: 10, b: 'abc' };         // 正常, 这个对象符合接口data定义的数据结构
let obj2: data = { a: 10 };                    // 报错, 缺失b属性
let obj3: data = { a: 10, b: true };        // 报错, b属性类型不对
let obj4: data = { a: 10, b: true, c:1 };  // 报错, 多了c属性
泛型

为什么要泛型
  • 假设有一个方法,可以传入任意多个数字,组成数组并返回
[AppleScript] 纯文本查看 复制代码
function createArray(...arg: number[]): number[] {
        return arg;
}

  • 假设我们现在要改造这个函数,让它可以实现更多需求,变得更通用
  • 改造需求是:传入的参数可以是数字,也可以是字符串等其他任意类型
  • 但是必须保证所有的参数类型一致,同时返回该类型构成的数组

[AppleScript] 纯文本查看 复制代码
function createArray(...arg: any[]): any[] {
        return arg;
}

  • 你可能会像上面那样写,但显然,这不能保证参数的类型是一致的
使用泛型
  • 要解决上面的问题,泛型就派上用场了
  • 泛型的使用方式是在函数的后面使用<>定义一个变量
  • 这个变量的值由调用者传入一个描述数据类型的字符串, 比如string/number/boolean等
  • 然后我们就可以使用这个变量来约束参数与返回值的类型

[AppleScript] 纯文本查看 复制代码
function createArray<Type>(...arg: Type[]): Type[] {
        return arg;
}

let arr1: Array<number> = createArray<number>(10, 20, 30);    // 正确
let arr2: Array<string> = createArray<string>('a', 'b', 'c')            // 正确
let arr3: Array<any> = createArray<string>('a', 'b', 10)               // 报错

泛型在类中的应用
  • 泛型除了可以应用在函数外, 还可以应用在类上
  • 看下面的代码实现了一个缓存数据的类, 目前这个类对于缓存的数据没有要求

[AppleScript] 纯文本查看 复制代码
class Cache {

    private data = {};

    set(key: string, val: any) {
        this.data[key] = val;
    }

    get(key: string): any {
        return this.data[key];
    }
}

let c: Cache = new Cache();
c.set('小红', 10);
c.get('小红');

  • 假设现在需求变了, 要求每个缓存只能存储同一种类型的数据,
  • 那可能你需要定义多个缓存类才能满足需求, 看下面的实现

[AppleScript] 纯文本查看 复制代码
class CacheNumber {

    private data = {};

    set(key: string, val: number) {
        this.data[key] = val;
    }

    get(key: string): number {
        return this.data[key];
    }
}

class CacheString {

    private data = {};

    set(key: string, val: string) {
        this.data[key] = val;
    }

    get(key: string): string {
        return this.data[key];
    }
}

  • 有了泛型后, 就不用向上面那样大费周折了, 而且支持的类型更多, 理论上无限
[AppleScript] 纯文本查看 复制代码
class Cache<Type> {

    private data = {};

    set(key: string, val: Type) {
        this.data[key] = val;
    }

    get(key: string): Type {
        return this.data[key];
    }
}

let c = new Cache<string>();
c.set('小红', 10);     // 报错, val必须为字符串
c.set('小红', '10');    // 正常

// 如果变量在定义便赋了值, 那么ts会自动推导变量的类型
// 如果要手动写类型的话, 必须声明一致的泛型类型, 看下面例子
let c2: Cache = new Cache<number>();                     // 报错
let c3: Cache<string> = new Cache<number>();       // 报错
let c3: Cache<number> = new Cache<number>();    // 正常

使用泛型定义数组
之前我们在定义数组类型时是这样写的
[AppleScript] 纯文本查看 复制代码
let arr: number[] = [];
arr.push(10);        // 正常
arr.push('abx');    // 报错

学习了泛型之后还可以这样写
[AppleScript] 纯文本查看 复制代码
let arr: Array<number> = [];
arr.push(10);        // 正常
arr.push('abx');    // 报错


2 个回复

倒序浏览
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马