Typescript中的接口和抽象类有什么区别?

时间:2018-05-01 03:01:21

标签: typescript oop

我写了几行代码来试验和区分这两者:interfaceabstract class

我发现他们有同样的限制。

interface IPerson {
  name: string;
  talk(): void;
}

interface IVIP {
  code: number;
}

abstract class Person {
  abstract name: string;
  abstract talk(): void;
}

class ManagerType1 extends Person {
  // The error i get is that i need to implement the talk() method
  // and name property from its base class.
}

class ManagerType2 implements IPerson {
  // The error i get is that i need to implement the talk() method 
  // and the name property from the interface.
}


class ManagerType3 implements IPerson, IVIP {
  // Now the error i get is that i need to implement all the 
  // properties and methods of the implemented interfaces to the derive class
}

正如我所发现的那样,这两者之间没有明显的区别,因为它们都实现了相同的限制。我注意到的唯一的事情是 inheretance 实施

  1. 一个类只能扩展到一个基类
  2. 一个类可以实现多个接口。
  3. 我抓到了吗?如果是的话我什么时候需要使用?

      

    更新

    我不知道是否是正确的答案,但你可以根据自己的情况真正使用BOTH。 OOP非常酷。

    class ManagerType3 extends Person implements IPerson, IVIP {
      // Now the restriction is you need to implement all the abstract
      // properties and methods in the based class and all 
      // the properties and methods from the interfaces
    }
    

3 个答案:

答案 0 :(得分:6)

TypeScript的一个更大的区别是(抽象)类在运行时可用,而接口只是编译时。这意味着您不能使用instanceof和接口。

let x: any;

if (x instanceof IPerson) { // Error: 'IPerson' only refers to a type, but is being used as a value here.

}

if (x instanceof Person) { // OK

}

如果你真的不需要运行时类型,比如上面的例子,或者只想在具体类中实现,那就去接口吧。因为它们只是编译时间,所生成的JS的大小会更小。

答案 1 :(得分:4)

接口

interface合同,用于定义属性以及实现它的对象可以执行的操作。例如,您可以定义可以执行 Plumber 电工的内容:

interface Electrician {
  layWires(): void
}

interface Plumber {
  layPipes(): void
}

然后,您可以使用接口的服务:

function restoreHouse(e: Electrician, p: Plumber) {
  e.layWires()
  p.layPipes()
}

请注意,您必须实现接口的方式是免费的。您可以通过实例化一个类或使用一个简单的对象来实现:

let iAmAnElectrician = {
  layWires: () => { console.log("Work with wires…") }
}

界面在运行时根本不存在,因此无法进行内省。它是处理对象编程的经典JavaScript方法,但在定义的契约的编译时具有良好的控制。

抽象类

class 是合同和工厂的实施abstract class也是一种实现,但不完整。特别是,抽象类在运行时存在,即使它只有抽象方法(然后可以使用instanceof)。

定义抽象类时,通常会尝试控制进程的实现方式。例如,你可以这样写:

abstract class HouseRestorer {
  protected abstract layWires(): void
  protected abstract layPipes(): void
  restoreHouse() {
    this.layWires()
    this.layPipes()
  }
}

这个抽象类HouseRestorer定义如何使用方法layWireslayPipes,但是由子类来实现专门的处理在它可以使用之前。

抽象类是传统的OOP方法,在JavaScript中并不常见。

这两种方法都可以完成同样的事情。但它们是解决问题的两种不同方式。这并不代表他们相互值得。

答案 2 :(得分:3)

你是对的,但第二个区别是抽象类可以有方法实现。