覆盖打字稿中的私有方法

时间:2020-09-27 00:04:21

标签: typescript

注意到带有公共方法message()的该版本可以编译,并且greet()可以按预期工作,

class Foo {
    public greet() {
        console.log(`Hello, ${this.getMessage()}`);
    }
    getMessage() : string {
        return "I am Foo"
    }
}

class Goo extends Foo {
    getMessage() : string {
        return "I am Goo";
    }
}

但将getMessage()标记为私有后,类Goo不再编译:

class Foo {
    public greet() {
        console.log(`Hello, ${this.getMessage()}`);
    }
    private getMessage() : string {
        return "I am Foo"
    }
}

class Goo extends Foo {
    private getMessage() : string {
        return "I am Goo";
    }
}

我经常使用私有方法来分解较大的方法,方法是摘录低级代码块以提高可读性,正如该主题的许多书所建议的那样,并且我将它们私有化,因为它们不打算被该类的使用者调用,但由于某种原因,当需要针对我的基类的某些子类修改这些较低级别的方法之一时,打字稿对我不利。

实际上,除了必须在扩展类中实现public方法之外,或者通过将支持方法包括在基类的public接口中来暴露支持方法的“脏衣服”,还有其他方法可以做到这一点。子班?

我还想问一个有趣的问题,打字稿作者对于这种看似任意规则的动机是什么,即公共方法可以被覆盖而私有方法不能被覆盖?

1 个答案:

答案 0 :(得分:1)

正如bryan60所说,请使用protected修饰符:

class Foo {
  public greet() {
    console.log(`Hello, ${this.getMessage()}`);
  }

  protected getMessage(): string {
    return "I am Foo";
  }
}

class Goo extends Foo {
  protected getMessage(): string {
    return "I am Goo";
  }
}

const goo = new Goo();
goo.greet(); // Hello, I am Goo

来自the handbook

protected修饰符的作用类似于private修饰符,不同之处在于声明的protected成员也可以在派生类中访问。

例如:

// Property 'getMessage' is protected and only accessible within class 'Goo'
// and its subclasses.
goo.getMessage();

class Hoo extends Goo {
  public getMessage(): string {
    return "I am Hoo";
  }

  public tryToGetGoosMessage(goo: Goo): string {
    // Property 'getMessage' is protected and only accessible through an
    // instance of class 'Hoo'.
    return goo.getMessage();
  }

  public doOtherHoosHoo(hoo: Hoo) {
    // ok, this is inside Hoo
    hoo.hoo();
  }

  protected hoo() {}
}

const hoo = new Hoo();
// ok, getMessage is public in Hoo
hoo.getMessage();

// Class 'Joo' incorrectly extends base class 'Hoo'.
//  Property 'getMessage' is protected in type 'Joo' but public in type 'Hoo'.
class Joo extends Hoo {
  protected getMessage(): string {
    return "I am Joo";
  }
}

Playground link