调用超超类的方法

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)

Est*_*ask 7

祖父母方法可以通过向上爬原型链来到达:

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)


Tit*_*mir 6

当我质疑要求您执行此操作的设计时,您可以通过获取A.prototype并使用的原始方法来轻松地做到这一点call

class C extends B { 
    notify() { alert("C") }

    callA() {
        A.prototype.notify.call(this);
    }
}
Run Code Online (Sandbox Code Playgroud)