TypeScript学习5-接口与类的应用

2019-07-16 admin

概述和对比

接口和类在实际使用中,一般都是配合使用的。我们来对比一下:

  • 接口可以声明一个类的结构,包含属性和方法,但它只是给出一个声明,没有访问修饰符,没有具体的方法实现,没有构造函数,也不可以被实例化。
  • 接口是一个对外的协商、约定。继承后才可以实例化,继承的时候必须实现声明。可以多重继承。
  • 是也是声明一个类的结构,包含属性和方法,有访问修饰符,有具体的方法实现,有构造函数,可以实例化(抽象类下面说)。继承的时候,可以覆盖,也可以继承使用父类实现。
  • 抽象类也是类,不过它可以包含接口类似的特性:普通方法包含实现,抽象方法是不包含实现的;抽象类不能实例化。继承后才可以实例化,继承的时候必须实现抽象声明,其他声明和普通类一样。

补充说明一下,这里的接口、类与纯正的面向对象语言Java比,有一些不同的地方,有兴趣的可以自行了解。

接口与类的使用场景

这里将给一个稍微复杂一点的例子:旅行社运送旅客。

定义接口

这里我们定义了几类接口:旅客、载客、位置、运送,目的就是声明规范,实现了这些接口的类就可以被用来做这些事情。

// 旅客
interface Passgener {
    name: string;
}

// 载客
interface Carriable {
  passengers: Passgener[];
  getUp (...passengers: Passgener[]): number;
  getOff (): number;
}

// 位置
interface Positioned {
    x: number;
    y: number;
}

// 常量:初始位置
const positionOrigin: Positioned = { x: 0, y: 0 };

// 运送
interface Moveable {
    position: Positioned;
    moveTo(Positioned: Positioned): Positioned;
}

实现具体类

这里我实现了两个类:小汽车、巴士,这两个类均实现了载客、运送接口,也就是说明它们是拥有这些能力的。

// 小汽车
class Car implements Carriable, Moveable {
  passengers: Passgener[];
  position: Positioned;
  capacity: number;

  constructor(capacity: number) {
    this.passengers = [];
    this.position = positionOrigin;
    this.capacity = capacity;
  }

  getUp (...passengers: Passgener[]): number {
    if (passengers.length > this.capacity) {
      throw new Error(`This car can carry ${this.capacity} passengers!`);
    }
    console.log(
            `This car carries ${passengers.map(item => item.name).join(',')}`
        );
    return this.passengers.push(...passengers);
  }

  getOff (): number {
    return this.passengers.splice(0).length;
  }

    moveTo(position: Positioned): Positioned {
        Object.assign(this.position, position);
        console.log(
            `This car carries ${this.passengers.map(item => item.name).join(',')} to [${
                this.position.x
            }, ${this.position.y}]`
        );
        return this.position;
    }
}

// 巴士
class Bus implements Carriable, Moveable {
  passengers: Passgener[];
  position: Positioned;
  capacity: number;

  constructor(capacity: number) {
    this.passengers = [];
    this.position = positionOrigin;
    this.capacity = capacity;
  }

  getUp (...passengers: Passgener[]): number {
    if (passengers.length > this.capacity) {
      throw new Error(`This Bus can carry ${this.capacity} passengers!`);
    }
    console.log(
            `This Bus carries ${passengers.map(item => item.name).join(',')}`
        );
    return this.passengers.push(...passengers);
  }

  getOff (): number {
    return this.passengers.splice(0).length;
  }

    moveTo(position: Positioned): Positioned {
    Object.assign(this.position, position);
    console.log(
            `This Bus carries ${this.passengers.map(item => item.name).join(',')} to [${
                this.position.x
            }, ${this.position.y}]`
        );
        return this.position;
    }
}

实现功能

具体类定义出来了,我们就可以实现功能,我们定义一个旅行社,由旅行社来运送旅客。

// 旅行社
class TravelAgency {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  carrying (carrier: Carriable & Moveable, position: Positioned, ...passengers: Passgener[]): Positioned {
    carrier.getUp(...passengers);
    return carrier.moveTo(position);
  }

}

// 实例化对象
let t1 = new TravelAgency("t1");
let c1 = new Car(4);
let b1 = new Bus(30);

// 实现功能
t1.carrying(c1, {x: 10, y: 60}, {name: 'Jack'}, {name: 'Tom'});
t1.carrying(b1, {x: 10, y: 60}, {name: 'Jack'}, {name: 'Tom'}, {name: 'Mary'}, {name: 'Joe'});

抽象类的使用场景

上面已经把完整的功能实现出来了,但是我们可以看到,Car和Bus的代码还是有冗余的。这里我们就可以通过抽象类来做一些优化。

我们先实现一个交通工具的抽象类,然后继承实现轮船类。我们可以发现抽象类已经实现的方法,子类是无需重复实现的。只有抽象出来的必须子类实现的才需要实现。

// 交通工具
abstract class Vehicle implements Carriable, Moveable {
  name: string;
  passengers: Passgener[];
    position: Positioned;
  capacity: number;

  // 抽象方法
  abstract run(speed: number): void;

  getUp (...passengers: Passgener[]): number {
    if (passengers.length > this.capacity) {
      throw new Error(`This ${this.name} can carry ${this.capacity} passengers!`);
    }
    console.log(
            `This ${this.name} carries ${passengers.map(item => item.name).join(',')}`
        );
    return this.passengers.push(...passengers);
  }

  getOff (): number {
    return this.passengers.splice(0).length;
  }

    moveTo(position: Positioned): Positioned {
        Object.assign(this.position, position);
        console.log(
            `This ${this.name} carries ${this.passengers.map(item => item.name).join(',')} to [${
                this.position.x
            }, ${this.position.y}]`
        );
        return this.position;
    }
}

// 轮船
class Ship extends Vehicle {
  constructor(capacity: number) {
    super();
        this.passengers = [];
        this.position = positionOrigin;
        this.capacity = capacity;
  }

  // 抽象方法必须实现 
  run(speed: number) {
    // todo, run as a ship...
    console.log(`This ${this.name} running at ${speed}km/h.`);
  }
}

到此介绍完了接口和类的基本使用场景,再次体会一下关键字:抽象、继承

[转载]原文链接:https://segmentfault.com/a/1190000019780468

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-69911.html

文章标题:TypeScript学习5-接口与类的应用

相关文章
html5+JavaScript教程-微信打飞机小游戏源码
js // JavaScript Document var c = document.getElementById("dotu"); var cxt = c.getContext("2d&q...
2015-11-12
js性能优化 如何更快速加载你的JavaScript页面
确保代码尽量简洁 不要什么都依赖JavaScript。不要编写重复性的脚本。要把JavaScript当作糖果工具,只是起到美化作用。别给你的网站添加大量的JavaScript代码。只有必要的时候用一下。只有确实能改善用户体验的时候用一下。 ...
2015-11-12
10个强大的纯CSS3动画案例分享
我们的网页外观主要由CSS控制,编写CSS代码可以任意改变我们的网页布局以及网页内容的样式。CSS3的出现,更是可以让网页增添了不少动画元素,让我们的网页变得更加生动有趣,并且更易于交互。本文分享了10个非常炫酷的CSS3动画案例,希望大家...
2015-11-16
2015年JavaScript或“亲库而远框架”
2014年过去了,作为一个JavaScript开发者很难满怀信心的去“挽回”一个特定的库或技术,即便是强大的Angular,似乎也因为最近的一些事情而动摇。 2014年10月的ng-europe会议上,Angular开发者团队透露了一个关于...
2015-11-12
v-charts | 饿了么团队开源的基于 Vue 和 ECharts 的图表工具
在使用echarts生成图表时,经常需要做繁琐的数据类型转化、修改复杂的配置项,v-charts的出现正是为了解决这个 痛点。基于Vue2.0和echarts封装的v-charts图表组件,只需要统一提供一种对前后端都友好的数据格式 设置简...
2018-05-24
国内外html5游戏引擎排行
一个好的HTML5游戏引擎,能够大大简化游戏的开发实现。 排名列表: Construct 2 ImpactJS EaselJS pixi.js Phaser GameMaker Three.js PlayCanvas Turbulenz ...
2015-11-12
详解HTML5游戏玩家流失原因
对任何类型的电子游戏来说,玩家流失都是一个无法回避的问题。玩家为什么离开游戏?近日,HTML5游戏设定师纳森·洛维托(Nathan Lovato)在游戏开发者网站Gamasutra撰写文章,解读了玩家离开游戏的16个理由。 HTML5游戏 ...
2015-11-12
YouTube正式默认使用HTML5视频播放器
YouTube视频网站现在默认使用HTML5播放器,这意味着更好的性能、 稳定性、 电池寿命和甚至是更好的安全性。现在用户通过Chrome、IE 11、Safari 8和Beta版本的Firefox进行浏览的时候都默认使用HTML5视频播放...
2015-11-12
从2014年的发展来展望JS的未来将会如何
<font face="寰�杞�闆呴粦, Arial, sans-serif ">2014骞达紝杞�浠惰�屼笟鍙戝睍杩呴€燂紝鍚勭�嶈��瑷€灞傚嚭涓嶇┓锛屼互婊¤冻鐢ㄦ埛涓嶆柇鍙樺寲鐨勯渶姹傘€傝繖浜涜��...
2015-11-12
12个你未必知道的CSS小知识
虽然CSS并不是一种很复杂的技术,但就算你是一个使用CSS多年的高手,仍然会有很多CSS用法/属性/属性值你从来没使用过,甚至从来没听说过。 1.CSS的color属性并非只能用于文本显示 对于CSS的color属性,相信所有Web开发人员...
2015-11-12
回到顶部