调用超级超类的方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了调用超级超类的方法相关的知识,希望对你有一定的参考价值。
当每个类包含一个具有相同名称的方法时,我在访问层次结构中的方法时遇到问题。
class A {
constructor(private name: string) { }
notify() { alert(this.name) }
}
class B extends A {
constructor() {
super("AAA")
}
notify() {alert("B") }
}
class C extends B {
notify() { alert("C") }
callA() {
this.notify(); // this alerts "C"
super.notify(); // this alerts "B"
// How to call notify() of the class A so it alerts "AAA"?
}
}
new C().callA();
答案
虽然我质疑要求你这样做的设计,你可以通过获得A.prototype
的原始方法并使用call
轻松解决这个问题:
class C extends B {
notify() { alert("C") }
callA() {
A.prototype.notify.call(this);
}
}
另一答案
爬上原型链可以达到祖父母方法:
class C extends B {
notify() { alert("C") }
callA() {
this.notify(); // this alerts "C"
const grandparentNotify = super.__proto__.notify;
grandparentNotify.call(this); // this alerts "AAA"
}
}
__proto__
用于说明目的,因为获取对象原型的正确方法是Object.getPrototypeOf
。请注意,grantparent原型的super.__proto__
链在实现之间可能不同(例如TypeScript和native)。
不应该达到祖父母方法,因为这表明了设计问题;孙子不应该知道祖父母的方法。在方法中使用call
是类设计出错的另一个标志。
如果需要在扩展类中使用来自另一个类的方法(它是否是祖父母并不重要),这应该通过mixin明确地完成。由于C
不需要所有祖父方法并且需要避免命名冲突,因此应该直接分配方法:
interface C {
grandparentNotify(): void;
}
class C extends B {
notify() { alert("C") }
callA() {
this.notify(); // this alerts "C"
this.grandparentNotify(); // this alerts "AAA"
}
}
C.prototype.grandparentNotify = A.prototype.notify;
接口被合并,并且通过键入系统接受grandparentNotify
作为C
方法。这种方式看起来很原始,但它是分配方法的惯用方法。
更平滑的方式提供一些开销但不需要接口合并是一个getter:
class C extends B {
notify() { alert("C") }
get grandparentNotify() {
return A.prototype.notify;
}
callA() {
this.notify(); // this alerts "C"
this.grandparentNotify(); // this alerts "AAA"
}
}
以上是关于调用超级超类的方法的主要内容,如果未能解决你的问题,请参考以下文章
为啥我不能将 B 的超类对象放入 Container<?超级B>? [复制]