调用超级超类的方法

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"
    }
}

以上是关于调用超级超类的方法的主要内容,如果未能解决你的问题,请参考以下文章

指定的初始化程序缺少对超类的指定初始化程序的超级调用

MATLAB:从 parfor 调用超类的方法

为啥我不能将 B 的超类对象放入 Container<?超级B>? [复制]

如何从别处调用 Objective-C 对象的超类的方法?

无法在初始化为超类的 ArrayList 中调用派生类的方法

Swift:“必须调用超类的指定初始化程序”错误,即使代码正在这样做