Mil*_*711 1 inheritance typescript ecmascript-6
当每个类都包含具有相同名称的方法时,在访问层次结构中的方法时遇到麻烦。
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();
Run Code Online (Sandbox Code Playgroud)
祖父母方法可以通过向上爬原型链来到达:
class C extends B {
notify() { alert("C") }
callA() {
this.notify(); // this alerts "C"
const grandparentNotify = super.__proto__.notify;
grandparentNotify.call(this); // this alerts "AAA"
}
}
Run Code Online (Sandbox Code Playgroud)
__proto__用于说明目的,因为获取对象原型的正确方法是Object.getPrototypeOf. 请注意,super.__proto__授权父原型的链在实现之间可能有所不同(例如 TypeScript 和本机)。
不应该达到祖父母方法,因为这表明设计有问题;孙子不应该知道祖父母的方法。in 方法的使用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;
Run Code Online (Sandbox Code Playgroud)
接口被合并,并被类型系统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"
}
}
Run Code Online (Sandbox Code Playgroud)
当我质疑要求您执行此操作的设计时,您可以通过获取A.prototype并使用的原始方法来轻松地做到这一点call:
class C extends B {
notify() { alert("C") }
callA() {
A.prototype.notify.call(this);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
885 次 |
| 最近记录: |