在 TypeScript 中扩展与实现纯抽象类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35990538/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Extending vs. implementing a pure abstract class in TypeScript
提问by Michael Liu
Suppose I have a pure abstract class (that is, an abstract class without any implementation):
假设我有一个纯抽象类(即没有任何实现的抽象类):
abstract class A {
abstract m(): void;
}
Like in C# and Java, I can extendthe abstract class:
就像在 C# 和 Java 中一样,我可以扩展抽象类:
class B extends A {
m(): void { }
}
But unlikein C# and Java, I can also implementthe abstract class:
但与C# 和 Java不同的是,我还可以实现抽象类:
class C implements A {
m(): void { }
}
How do classes B
and C
behave differently? Why would I choose one versus the other?
类B
和C
行为如何不同?为什么我会选择一个而不是另一个?
(Currently, the TypeScript handbookand language specificationdon't cover abstract classes.)
回答by toskv
The implementskeyword treats the A class as an interface, that means C has to implement all the methods defined in A, no matter if they have an implementation or not in A. Also there are no calls to super methods in C.
该工具关键字对待A类为一个接口,这意味着C具有实现所有A中所定义的方法,不管他们是否有在执行或不一个。在C 中也没有对 super 方法的调用。
extendsbehaves more like what you'd expect from the keyword. You have to implement only the abstract methods, and super calls are available/generated.
extends 的行为更像您对关键字的期望。您只需实现抽象方法,并且可以使用/生成超级调用。
I guess that in the case of abstract methods it does not make a difference. But you rarely have a classwith only abstract methods, if you do it would be much better to just transform it to an interface.
我想在抽象方法的情况下,它没有区别。但是你很少有一个只有抽象方法的类,如果你这样做,将它转换为interface会好得多。
You can easily see this by looking at the generated code. I made a playground example here.
通过查看生成的代码,您可以轻松看到这一点。我在这里做了一个游乐场的例子。
回答by Tao
I was led here because I had just been asking myself the same question and while reading the answers it ocurred to me that the choice will also affect the instanceof
operator.
我被带到这里是因为我刚刚问自己同样的问题,在阅读答案时,我发现选择也会影响instanceof
操作员。
Since an abstract class is an actual value that gets emitted to JS it can be used for runtime checks when a subclass extends it.
由于抽象类是发送给 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
回答by Cory
Building on @toskv's answer, if you extendan abstract class, you have to call super()
in the subclass's constructor. If you implementthe abstract class, you don't have to call super()
(but you have to implement all the methods declared in the abstract class, including private methods).
基于@toskv 的回答,如果您扩展抽象类,则必须调用super()
子类的构造函数。如果实现了抽象类,就不用调用了super()
(但是必须实现抽象类中声明的所有方法,包括私有方法)。
Implementing an abstract class instead of extending it could be useful if you want to create a mock class for testing without having to worry about the original class's dependencies and constructor.
如果您想创建一个用于测试的模拟类而不必担心原始类的依赖项和构造函数,那么实现一个抽象类而不是扩展它可能会很有用。
回答by Quentin 2
In the example of extends that you give you don't actually add anything new to the class. So it is extended by nothing. Although extending by nothing is valid Typescript it would seem to me that in this case 'implements' would be more appropriate. But at the end of the day they are equivalent.
在您提供的扩展示例中,您实际上并未向类添加任何新内容。所以它被无所扩展。尽管无所作为扩展是有效的 Typescript,但在我看来,在这种情况下,“实现”会更合适。但归根结底,它们是等效的。