【问题标题】:Extending vs. implementing a pure abstract class in TypeScript在 TypeScript 中扩展与实现纯抽象类
【发布时间】:2016-06-29 16:02:32
【问题描述】:

假设我有一个纯抽象类(即没有任何实现的抽象类):

abstract class A {
    abstract m(): void;
}

就像在 C# 和 Java 中一样,我可以扩展抽象类:

class B extends A {
    m(): void { }
}

但是不像在C#和Java中,我也可以实现抽象类:

class C implements A {
    m(): void { }
}

B 和 C 类的行为有何不同?为什么我会选择一个而不是另一个?

(目前,TypeScript handbook 和 language specification 不包括抽象类。)

【问题讨论】:

  • TypeScript 手册中现在有一个关于抽象类的部分。 typescriptlang.org/docs/handbook/classes.html感谢这个问题!我不知道 abstract 在 TS 中可用,这有助于我理解它。
  • @theUtherSide 链接的文档不知何故没有有一个class C implements A 的示例,这真是太神奇了。在阅读这些帖子之前,我什至不知道这是可能的,而且我最近在 ts 文档中很多。

标签: typescript abstract-class extends implements


【解决方案1】:

implements 关键字将 A 类视为一个接口,这意味着 C 必须实现 A 中定义的所有方法,无论它们是否有实现在 A 中。在 C 中也没有对超级方法的调用。

extends 的行为更像您对关键字的期望。您只需实现抽象方法,并且超级调用可用/生成。

我想在抽象方法的情况下它没有什么区别。但是你很少有一个只有抽象方法的类,如果你这样做的话,把它转换成一个接口会更好。

您可以通过查看生成的代码轻松看到这一点。我做了一个游乐场的例子here。

【讨论】:

  • 如果A 是一个纯抽象类,也许唯一可观察到的区别是instanceof 关键字的行为?我同意接口可能比纯抽象类更可取。但是,在 Angular 2 中,只有后者可以用作 DI 提供者令牌。
  • 确实,感谢您发现 instanceof 事物,我会将其添加到答案中以完成(您可以根据需要进行编辑)。至于 angular2,我想这是 angular2 的特定问题。 :)
  • @toskv,感谢您描述 'implements' 关键字对接口和类的适用性。例如,AngularJS 2.0 使用它来实现他们的“OnInit”类(而不是“接口”)。我环顾四周,你有这个参考。我在 TS 文档中看不清楚。
【解决方案2】:

我被带到这里是因为我刚刚问了自己同样的问题,在阅读答案时,我发现选择也会影响instanceof 运算符。

由于抽象类是发送给 JS 的实际值,它可以在子类扩展它时用于运行时检查。

abstract class A {}

class B extends A {}

class C implements A {}

console.log(new B() instanceof A) // true
console.log(new C() instanceof A) // false

【讨论】:

  • 感谢@Tao,这是一个纯粹且解释清楚的。另外我想为这个添加额外的信息,如果你删除抽象关键字,你会得到相同的结果,抽象与否并不重要。
【解决方案3】:

基于@toskv's answer,如果你扩展一个抽象类,你必须在子类的构造函数中调用super()。如果实现抽象类,则不必调用super()(但必须实现抽象类中声明的所有方法,包括私有方法)。

如果您想创建一个模拟类进行测试,而不必担心原始类的依赖项和构造函数,那么实现一个抽象类而不是扩展它可能会很有用。

【讨论】:

    【解决方案4】:

    在您提供的扩展示例中,您实际上并没有向该类添加任何新内容。所以它什么都没有扩展。尽管什么都不做扩展是有效的打字稿,但在我看来,在这种情况下,“实现”会更合适。但归根结底,它们是等价的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-03
      • 1970-01-01
      • 2022-07-08
      • 1970-01-01
      • 2016-08-26
      • 1970-01-01
      • 1970-01-01
      • 2021-12-14
      相关资源
      最近更新 更多