一起来学typescript入门知识(02) 类,变量声明,接口

in typescript with 0 comment

引用一段官方的类介绍

传统的JavaScript程序使用函数和基于原型的继承来创建可重用的组件,但对于熟悉使用面向对象方式的程序员来讲就有些棘手,因为他们用的是基于类的继承并且对象是由类构建出来的。 从ECMAScript 2015,也就是ECMAScript 6开始,JavaScript程序员将能够使用基于类的面向对象的方式。 使用TypeScript,我们允许开发者现在就使用这些特性,并且编译后的JavaScript可以在所有主流浏览器和平台上运行,而不需要等到下个JavaScript版本。

其实typescript的类的语法与java和c#十分的相似,如果有相关的经验可以很快适应。
类:

class Gamer {
    gamming: string;
    constructor(message: string) {
        this.gamming= message;
    }

    gamer(): string {
        return "Hello, world." + this.gamming;
    }
}

let gamer= new Gamer("I'm a gamer!");

看到这段类的代码是不是觉得十分熟悉?
我们声明了一个Gamer并在类里声明了一个初始化变量gamming,之后在constructor构造函数里添加了参数message并标注了类型string。在构造函数内初始化了变量gamming,并将message参数赋值给了类成员变量gamming
创建一个方法gamer,并标注了返回值为string类型,返回字符串**'hello, world.'并拼接上Gamer的成员变量gamming**。
最后声明了一个变量gamer并初始化一个新的Gamer对象!
这一系列操作和java,c#基本没什么区别,但是需要注意的是,返回值的声明是在方法名的后面!而所有类成员变量以及方法都需要使用this来调用~!

类的继承:
在面向对象编程中,基于类的程序设计模式最基本的就是使用类的继承来扩展现有类的功能与属性。

class Player {
  rtsPlayer: string = 'RTS player.';
  protected fpsPlayer: string = 'FPS player.';
  private info: string = 'player is a human.';

  constructor() {}

  sayHello(message: string): string{
    return 'I'm a ' + message;
  }

  playGame(): string{
    return 'I'm playing!';
  }
}

class FpsPlayer extends Player{
  private info = '我喜欢玩射击类游戏!';

  constructor() {
    console.log(this.sayHello(this.fpsPlayer));
    console.log(this.say(this.info));
    console.log(this.playGame());
  }

  say(message: string): string {
    return message;
  }

}

控制台输出如下:

I'm a FPS player.
我喜欢玩射击类游戏!
I'm playing!

类的继承:子类继承父类/超类的属性和方法。继承的属性和方法受修饰符的限制。子类可以直接使用this调用父类的方法和成员变量。

类成员变量的声明:

  1. private
    private,私有修饰符,被private修饰的变量和方法,只可以在本类进行使用。
  2. protected
    protected,保护修饰符,被protected修饰的变量和方法,不可以被第三方调用,可以在派生类中访问,参考前面示例。
  3. public
    public,公共修饰符,在typescript中,不加修饰符的变量和方法默认就是公共的,公共的变量和方法,可以在任何引用了该类的类中访问。

接口

TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。

function printLabel(labelledObj: { label: string }) {
  console.log(labelledObj.label);
}

let myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);

下面通过一个简单示例来观察接口是如何工作的:
类型检查器会查看printLabel的调用。 printLabel有一个参数,并要求这个对象参数有一个名为label类型为string的属性。 需要注意的是,我们传入的对象参数实际上会包含很多属性,但是编译器只会检查那些必需的属性是否存在,并且其类型是否匹配。 然而,有些时候TypeScript却并不会这么宽松,我们下面会稍做讲解。

下面我们重写上面的例子,这次使用接口来描述:必须包含一个label属性且类型为string:

interface LabelledValue {
  label: string;
}

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

LabelledValue接口就好比一个名字,用来描述上面例子里的要求。 它代表了有一个 label属性且类型为string的对象。 需要注意的是,我们在这里并不能像在其它语言里一样,说传给 printLabel的对象实现了这个接口。我们只会去关注值的外形。 只要传入的对象满足上面提到的必要条件,那么它就是被允许的。

还有一点值得提的是,类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。