为什么TS允许接口多重继承?

问题描述 投票:0回答:1

我正在学习有关扩展接口的 TypeScript。我无意中意识到 TypeScript 允许从多个类扩展接口。这让我感到惊讶,我进行了很多研究以找到更多信息,但直到现在,我还无法回答问题。

我想知道:虽然 TypeScript 阻止类从多个类继承(类有 2 个或更多直接基类),但为什么它允许一个接口直接从多个类扩展,如下代码所示:

```typescript
class Student{
    name:string = ''
}

class Employee {
    salary:number =0
}

interface Work_Study extends Student,Employee{
    description:string;
}

```
typescript oop inheritance multiple-inheritance prototypal-inheritance
1个回答
0
投票

一般来说,使用继承通常被认为是一种不好的做法。您需要记住一些好的做法:

  • 接口隔离原则(ISP):“任何代码都不应被迫依赖于它不使用的方法”。

  • 组合重用原则 (CRP):“类应该通过其组合(通过包含实现所需功能的其他类的实例)而不是从基类或父类继承来支持多态行为和代码重用。”

不允许使用多重继承,以避免钻石问题,并鼓励开发者遵守CRP原则。这是 ECMAScript 委员会关于 JavaScript 继承的设计决定。

关于您的问题 1. 您可以扩展多个接口以符合ISP的要求。例如:

interface Disposable {
  dispose: () => void;
}

interface Serializable {
  serialize: () => string;
}

class Student implements Disposable, Serializable {
    name:string = '';
    somethingElse: number = 0;
    serialize() {
      return JSON.stringify(this);
    }
    dispose() {
      // dispose logic
    }
}

如果只允许你实现一个接口,你就会鼓励开发者打破 ISP 原则。

使用多个接口意味着当你实现应用程序的其他部分时,这些部分不需要与

Student
耦合;它们只能与它们需要的方法耦合:

function cleanUp(something: Disposable) {
  something.dispose();
}

function serialzie(something: Serializable) {
  return something.serialize();
}

关于您的问题2和3:

  1. 是的,实现多个接口很常见。 这里是 TypeScript 代码本身的示例。

  2. 是的,与2相同。只有一个限制,钻石问题

interface Student {
    name:string;
    somethingElse: number;
}

interface Employee {
    salary:number;
    somethingElse: string;
}

// 'WorkStudy' cannot simultaneously extend types 'Student' and 'Employee'.
// Named property 'somethingElse' of types 'Student' and 'Employee' are not identical.
interface WorkStudy extends Student, Employee{
    description:string;
}

如果您想重用代码,唯一的选择是使用组合而不是继承:

interface IStudent {
    name:string;
}

interface IEmployee {
    salary:number;
}

class Student implements IStudent {
  constructor(public name: string) {}
}

class Employee implements IEmployee {
  constructor(public salary: number) {}
}

class WorkStudy implements IStudent, IEmployee{
  private _student: IStudent;
  private _employee: IEmployee;
  constructor(
    public description: string,
    student: IStudent,
    employee: IEmployee
  ) {
    this._employee = employee;
    this._student = student;
  }
  get salary() {
    return this._employee.salary;
  }
  get name() {
    return this._student.name;
  }
}

因此,您唯一的选择就是遵守 CRP。

© www.soinside.com 2019 - 2024. All rights reserved.