首页 > 解决方案 > 重写打字稿中的私有方法

问题描述

注意这个带有公共方法的版本可以按预期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";
    }
}

正如许多有关该主题的书籍所推荐的那样,我经常使用私有方法通过抽象出低级代码块来分解更大的方法以提高可读性,并且我将它们设为私有,因为它们不打算由类的消费者调用,而是为了当需要为我的基类的某些子类修改这些较低级别的方法之一时,打字稿对我不利。

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

另外,我想知道打字稿作者的动机是什么,因为这个看似任意的规则是公共方法可以被覆盖但私有方法不能被覆盖?

标签: typescript

解决方案


正如 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

来自手册

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

游乐场链接


推荐阅读