【问题标题】:Class 'B' incorrectly extends base class 'A' (two private methods named the same)类“B”错误地扩展了基类“A”(两个私有方法名称相同)
【发布时间】:2018-02-16 15:20:26
【问题描述】:

我收到了错误

“B”类错误地扩展了基类“A”。
类型具有私有属性“方法”的单独声明。

abstract class A {
  private method() {}
}

abstract class B extends A {
  private method() {}
}

A 类中的方法被注释掉时,错误就消失了。我该怎么做才能拥有两个名称相同的私有方法?

【问题讨论】:

  • 以不同的方式命名它们会起作用。
  • 我认为这是可以接受的。两者公开有效。
  • 这就是只使用 typescript 的问题,将其转换为纯 JavaScript,您可以按照代码的最终方式进行操作,
  • 你能不能把A转换成一个接口,把现有的A.method移到一个实现A的新抽象类中?
  • What can I do to have two private methods that are named the same? - 从另一个类扩展一个类时,您不能有两个命名相同的私有方法,如本文所述 - typescript derived class cannot have the same variable name? 可能重复

标签: javascript typescript


【解决方案1】:

由于 Typescript 位于 Javscript 之上,并且 Javascript 不允许继承的类对函数有不同的私有实现(所有函数最终都会在类的 prototype 上),因此 Typescript 不允许你这样做是有道理的去做这个。

如果允许这样做,您基本上将覆盖私有成员method,并且由于它被标记为私有,它可能不打算用于公共消费/覆盖。

如果您将其声明为公共/受保护的,您可以覆盖该函数

abstract class A {
    protected method() { }
}

abstract class B extends A {
    protected method() { }
}

或者,如果您真的想覆盖私有方法,您可以执行以下操作,尽管私有方法被标记为私有是有原因的,最好避免这种情况:

class B extends A {

}
(B.prototype as any)['method'] = function(this: B) {
}

【讨论】:

  • 既然所有方法在编译后都是公共的,而且 TypeScript 允许相同的公共方法,为什么它不支持相同的私有方法呢?无论如何,他们最终都会公开......
  • @GetOffMyLawn 你可以使用 TypeScript Playground 查看 JavaScript 以及为什么它不可能 typescriptlang.org/play/…
  • @GetOffMyLawn 好吧,打字稿不允许你做很多你可以在 JS 中做的事情。这里的原因是被标记为私有的方法是基类的一个实现细节,你甚至不应该知道它,更不用说重写它了
  • @GetOffMyLawn 由于该方法是私有的,因此您可能会在不知道它的情况下覆盖它,如果您真的非常想这样做,您仍然可以这样做,但至少您不会覆盖私有的实现细节错误..
【解决方案2】:

这一切都很奇怪,但如果你真的需要,试试这个:

class Foo {
    private go() {
    }
}

class Bar extends Foo {
    constructor() {
        super();
        this["go"] = this.foo;
    }

    private foo() {

    }
}

【讨论】: