首页 > 解决方案 > 打字稿继承中的覆盖函数

问题描述

我有一堂课:

  export class RestService {

  private baseUrl: string;

  constructor(protected http: HttpClient) {
    this.baseUrl = environment.LOCAL_URL;
  }

  public get<T>(resource: string, params?: HttpParams): Observable<T> {
    const url = this.PrepareUrl(resource);
    return this.http.get<T>(url, { params }).pipe(
      retry(2),
      catchError(this.catchBadResponse)
    );
  }

  public post<T>(resource: string, model: any): Observable<T> {
    const url = this.PrepareUrl(resource);
    const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
    return this.http.post<T>(url, model, { headers }).pipe(
      retry(2),
      catchError(this.catchBadResponse)
    );
  }

  public put<T>(resource: string, model: any): Observable<T> {
    const url = this.PrepareUrl(resource);
    return this.http.put<T>(url, model).pipe(
      retry(2),
      catchError(this.catchBadResponse)
    );
  }

  public delete(resource: string, id: any): Observable<any> {
    const url = this.PrepareUrl(resource) + `\\${id}`;
    return this.http.delete(url).pipe(
      retry(2),
      catchError(this.catchBadResponse)
    );
  }

  protected PrepareUrl(resource: string): string {
    return `${this.baseUrl}/${resource}`;
  }

  protected catchBadResponse(error: HttpErrorResponse) {
    console.log('error occured!');
    return throwError(error);
  }
}

和另一个扩展 RestService 类的类:

export class PersonRestService extends RestService {

  constructor(protected http: HttpClient) {
    super(http);

  }
  public get<T>(params?: HttpParams): Observable<T> {
    return super.get<T>('person', params);
  }

  public post<T>(model: any): Observable<T> {
    return super.post('person', model);
  }
}

我想覆盖子类中的一些函数,但我有来自 ide 的提示(错误):

'PersonRestService' 类型中的属性 'get' 不能分配给基本类型 'RestService' 中的相同属性。类型 '(params?: HttpParams) => Observable' 不可分配给类型 '(resource: string, params?: HttpParams) => Observable'。参数“params”和“resource”的类型不兼容。类型“字符串”不可分配给类型“HttpParams”.ts(2416)

我应该怎么办?

标签: angulartypescriptoopinheritance

解决方案


在打字稿中,我们不能 100% 覆盖方法;就像这个问题,我们不能覆盖遗留方法。有一个 qoute 说:“Favor Composition Is Over Inheritance”;所以我像下面这样更改代码片段:

1-不要更改 RestService:

export class RestService {

  private baseUrl: string;

  constructor(protected http: HttpClient) {
    this.baseUrl = environment.LOCAL_URL;
  }

  public get<T>(resource: string, params?: HttpParams): Observable<T> {
    const url = this.PrepareUrl(resource);
    return this.http.get<T>(url, { params }).pipe(
      retry(2),
      catchError(this.catchBadResponse)
    );
  }

  public post<T>(resource: string, model: any): Observable<T> {
    const url = this.PrepareUrl(resource);
    const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
    return this.http.post<T>(url, model, { headers }).pipe(
      retry(2),
      catchError(this.catchBadResponse)
    );
  }

  public put<T>(resource: string, model: any): Observable<T> {
    const url = this.PrepareUrl(resource);
    return this.http.put<T>(url, model).pipe(
      retry(2),
      catchError(this.catchBadResponse)
    );
  }

  public delete(resource: string, id: any): Observable<any> {
    const url = this.PrepareUrl(resource) + `\\${id}`;
    return this.http.delete(url).pipe(
      retry(2),
      catchError(this.catchBadResponse)
    );
  }

  protected PrepareUrl(resource: string): string {
    return `${this.baseUrl}/${resource}`;
  }

  protected catchBadResponse(error: HttpErrorResponse) {
    console.log('error occured!');
    return throwError(error);
  }
}

2-删除 PersonRestService 形式的 RestService 扩展并在构造函数中注入 RestService:

export class PersonRestService {

  constructor(private restService: RestService) {
  }
  public get<T>(params?: HttpParams): Observable<T> {
    return this.restService.get<T>('person', params);
  }
}

完毕!现在我可以玩代码了。


推荐阅读