接口

object表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型,我们一般使用接口来定义对象的类型.
typeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。

  1. interface Car {
  2. speed: number;
  3. color?: string; // 可选属性
  4. readonly price: number // 只读属性
  5. [propName: string]: any // 额外属性
  6. }
  7. let car1 : Car = {
  8. speed: 200,
  9. price: 300,
  10. color: 'blue',
  11. }
  12. let car2 : Car = {
  13. speed: 100,
  14. price: 200,
  15. name: 'mycar'
  16. }
  17. car2.price = 400 // error

上面定一个了一个接口,赋值的时候,变量的形状必须和接口的形状保持一致。但是接口包含了,可选属性,只读属性,额外属性。这会允许变量会不一样。

  • 可选属性在属性后面添加一个?,表示变量中该属性可以不存在。
  • 只读属性在属性前面加上readonly即可,表示变量对对象赋值后不可变更(只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候)
  • 额外属性通常以[propName: [string]]: any表示,表示对象允许有一个值任意属性

需要注意的是,一旦定义了任意属性的类型,那么确定属性和可选属性的类型都必须是它的类型的子集.
任意属性的值允许是string,但是可选属性speed的值却是 number,number 不是 string 的子属性,因此会报错。

  1. interface Car {
  2. speed: number;
  3. color?: string;
  4. [propName: string]: string
  5. }
  6. let car2 : Car = { // error
  7. speed: 100,
  8. color: 'blue',
  9. name: 'mycar'
  10. }

接口同样可以应用于数组:NumberArray 表示: index 的类型是 number,值的类型也是 number

  1. interface NumberArray {
  2. [index: number]: number;
  3. }
  4. let foo: NumberArray = [1, 2, 4, 3, 9];
  5. interface StringArray {
  6. [index: number]: string;
  7. }
  8. let bar: StringArray = ['1', '2', '4', '3', '9'];

Typescript中类的写法如下:

  1. class Animal {
  2. name: string;
  3. constructor(name: string) {
  4. this.name = name;
  5. }
  6. sayHi(): string {
  7. return `My name is ${this.name}`;
  8. }
  9. }
  10. let a: Animal = new Animal('Jack');
  11. console.log(a.sayHi()); // My name is Jack

public private 和 protected

  • public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的
  • private 修饰的属性或方法是私有的,不能在声明它的类的外部访问
  • protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的

当成员被标记pubilc后,所有直接访问实例当属性都是允许的。

  1. class Person {
  2. public name: string;
  3. public constructor(name: string) {
  4. this.name = name;
  5. }
  6. }
  7. let a = new Person('Jack');
  8. console.log(a.name); // Jack
  9. a.name = 'Tom';
  10. console.log(a.name); // Tom

当成员被标记成 private时,它就不能在声明它的类的外部访问

  1. class Animal {
  2. Person name: string;
  3. constructor(name: string) { this.name = name; }
  4. }
  5. let a = new Person('Jack');
  6. console.log(a.name); // error
  7. a.name = 'Tom';
  8. console.log(a.name); // error

protected修饰符与 private修饰符的行为很相似,但有一点不同, protected成员在派生类中仍然可以访问。

  1. class Person {
  2. protected name: string;
  3. public constructor(name: string) {
  4. this.name = name;
  5. }
  6. }
  7. class Sporter extends Person {
  8. constructor(name: string) {
  9. super(name);
  10. console.log(this.name);
  11. }
  12. }

抽象类
抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化, 不同于接口,抽象类可以包含成员的实现细节。abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法.并且抽象类中的抽象方法必需被子类实现。

  1. abstract class Animal {
  2. abstract makeSound(): void;
  3. move(): void {
  4. console.log('roaming the earch...');
  5. }
  6. }
  7. class Cat extends Animal {
  8. makeSound() {
  9. console.log('meao!meao!')
  10. }
  11. }

类实现接口
实现(implements)是面向对象中的一个重要概念。一般来讲,一个类只能继承自另一个类,有时候不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口(interfaces),用 implements 关键字来实现。这个特性大大提高了面向对象的灵活性

  1. interface Alarm {
  2. alert();
  3. }
  4. class Door {
  5. }
  6. class SecurityDoor extends Door implements Alarm {
  7. alert() {
  8. console.log('SecurityDoor alert');
  9. }
  10. }
  11. class Car implements Alarm {
  12. alert() {
  13. console.log('Car alert');
  14. }
  15. }

一个类可以实现多个接口

  1. interface Alarm {
  2. alert();
  3. }
  4. interface Light {
  5. lightOn();
  6. lightOff();
  7. }
  8. class Car implements Alarm, Light {
  9. alert() {
  10. console.log('Car alert');
  11. }
  12. lightOn() {
  13. console.log('Car light on');
  14. }
  15. lightOff() {
  16. console.log('Car light off');
  17. }
  18. }

接口继承接口
接口与接口之间可以是继承关系

  1. interface Alarm {
  2. alert();
  3. }
  4. interface LightableAlarm extends Alarm {
  5. lightOn();
  6. lightOff();
  7. }

接口继承类
接口也可以继承类

  1. class Point {
  2. x: number;
  3. y: number;
  4. }
  5. interface Point3d extends Point {
  6. z: number;
  7. }
  8. let point3d: Point3d = {x: 1, y: 2, z: 3};