Typescript 调用超类的方法

Typescript 调用超类的方法,typescript,inheritance,ecmascript-6,Typescript,Inheritance,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 { no

当每个类都包含一个同名的方法时,我在访问层次结构中的方法时遇到问题

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"
    }
}
\uuuu proto\uuuu
用于说明目的,因为获取对象原型的正确方法是
object.getPrototypeOf
。请注意,grantparent原型的
super.\uuuuu proto\uuuuu
链在不同的实现(例如,TypeScript和native)之间可能有所不同

不应达到祖父母方法,因为这表明存在设计问题;孙子不应该知道祖父母的方法。在方法中使用
call
是类设计出错的另一个标志

如果需要在扩展类中使用来自另一个类的方法(它是否是祖辈并不重要),那么应该通过。由于
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;
接口被合并,并且
祖父母通知
被打字系统接受为
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"
    }
}

没有任何构造允许您这样做——但您具体想做什么?重写方法时应始终小心。