假设我有一个纯抽象类(即没有任何实现的抽象类):
abstract class A {
abstract m(): void;
}
像在C#和Java中一样,我可以扩展抽象类:
class B extends A {
m(): void { }
}
但是与C#和Java不同,我还可以实现抽象类:
class C implements A {
m(): void { }
}
类B
和C
行为如何不同?为什么我要选择一个?
class C implements A
。在阅读这些文章之前,我什至不知道这是有可能的,而且最近我在ts文档中访问了很多。
Answers:
该工具关键字对待A类为一个接口,这意味着C具有实现所有A中所定义的方法,不管他们是否有在执行或不一个。也没有在C中调用super方法。
extend的行为更像您希望从关键字获得的内容。您仅需实现抽象方法,并且超级调用可用/已生成。
我猜想在抽象方法的情况下没有什么区别。但是,您很少有只包含抽象方法的类,如果这样做,将其转换为接口会更好。
通过查看生成的代码,您可以轻松地看到这一点。我在这里做了一个游乐场的例子。
A
是纯抽象类,也许唯一可观察到的区别就是instanceof
关键字的行为?我同意接口可能比纯抽象类更好。但是,在Angular 2中,只有后者可以用作DI提供程序令牌。
我之所以被带到这里,是因为我一直在问自己同样的问题,并且在阅读答案时发现,选择也会影响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
以@toskv的答案为基础,如果扩展抽象类,则必须调用super()
子类的构造函数。如果实现抽象类,则不必调用super()
(但必须实现在抽象类中声明的所有方法,包括私有方法)。
如果要创建一个模拟类进行测试而不必担心原始类的依赖项和构造函数,则实现一个抽象类而不是对其进行扩展可能会很有用。
abstract
TS中有没有可用的方法,这有助于我理解它。