笔记2 | 青训营

70 阅读4分钟

接口和类是面向对象编程 (OOP) 的基本部分。Typescript 是一种面向对象的 JavaScript 语言,从 ES6 及更高版本开始,它支持 OOP 功能,如接口、类和封装。

但是我们什么时候应该同时使用接口、类或两者呢?

TypeScript 中的类是什么?

在开始之前,我们需要知道什么是 TypeScript 类。在面向对象的编程中,类是一个蓝图或模板,通过它我们可以创建具有特定属性和方法的对象。

Typescript 为类型检查提供了额外的语法,并将代码转换为在任何平台和浏览器上运行的干净 JavaScript。类涉及代码的所有阶段。将 TypeScript 代码转换为 JavaScript 文件后,您可以在最终文件中找到它们。

该类定义对象的模板,或者它是什么以及它做什么。让我们创建一个包含属性和方法的简单类,以便我们可以看到它的行为方式。

首先,我将通过以下代码行创建一个类:Developer

class Developer {
  name?: string; 
  position?: string; 
}

我们用属性和 .它们包含像 和 这样的类型。name position string undefined

接下来,让我们使用关键字通过类创建一个对象:Developer new

const developer = new Developer();
developer.name 
developer.position 

当我们调用 时,它返回,因为我们没有分配初始值。为了在 TypeScript 中创建带有值的对象,我们可以使用构造函数方法。构造函数方法用于初始化和创建对象。developer.name undefined

现在我们使用以下代码更新我们的类:Developer

class Developer {
  name: string; 
  position: string; 

  constructor(name: string, position: string) {
    this.name = name;
    this.position = position;
  }
}

在上面的代码中,我们添加了使用值初始化属性的方法。constructor

现在我们可以使用以下代码设置:name Gapur position Frontend Developer

const developer = new Developer("Gapur", "Frontend Developer");
developer.name // it outputs Gapur
developer.position // it outputs Frontend Developer

最后,正如我前面提到的,该类具有对象应如何操作的方法。在这种情况下,任何开发人员都开发应用程序,因此,该类具有 方法 .Developer``develop

因此,对象可以执行开发操作:developer

class Developer {
  name: string;
  position: string;

  constructor(name: string, position: string) {
    this.name = name;
    this.position = position;
  }

  develop(): void {
    console.log('develop an app');
  }
}

如果我们运行该方法,它将执行以下语句:develop console.log

developer.develop()

什么是 TypeScript 中的接口?

接口是一种结构,其作用类似于应用程序中的协定,或类遵循的语法。该界面也称为鸭子打印或子类型。

该接口包括一个方法和字段声明,无需实现。我们不能用它来创造任何东西。实现接口的类必须具有所有字段和方法。因此,我们使用它们进行类型检查。only 当 TypeScript 将所有代码转换为 JavaScript 时,该接口将从 JavaScript 文件中消失。因此,它是开发阶段的有用工具。

我们应该为以下用途使用接口:

  • 验证属性的特定结构
  • 对象作为参数
  • 从函数返回的对象
interface InterfaceName {
  // variables;
  // methods;
}

我们只能在接口主体中包含变量和方法的声明。让我们为前面的类创建一个接口:IDeveloper Developer

interface IDeveloper {
  name: string
  position: string
  develop: () => void
}

class Developer implements IDeveloper {
  name: string;
  position: string;

  constructor(name: string, position: string) {
    this.name = name;
    this.position = position;
  }

  develop(): void {
    console.log('app');
  }
}

在上面的代码中,我们的接口包含变量和.它还包括该方法。因此,该类实现了接口。因此,它必须定义两个变量和一个方法。IDeveloper name position develop Developer IDeveloper

如果类没有实现任何变量,TypeScript 将显示一个错误:Developer

class Developer implements IDeveloper {
  // error Class 'Developer' incorrectly implements interface 'IDeveloper'.
  name: string;

  constructor(name: string, position: string) {
    this.name = name;
    this.position = position;
  }

  develop(): void {
    console.log('app');
  }
}

接口与类

那么我们什么时候应该使用类,什么时候应该使用接口呢?

我将使用前一个类用静态方法创建一个类:Developer

class Developer {
  static develop(app: { name: string, type: string }) {
    return { name: app.name, type: app.type };
  }
}

现在,我们可以在不实例化类的情况下调用该方法:Developer.develop()

Developer.develop({ name: 'whatsapp', type: 'mobile' })
// outputs: { "name": "whatsapp", "type": "mobile" } 

此外,我们可以在 TypeScript 中使用类进行类型检查。让我们使用以下代码创建一个类:App

class App {
  name: string;
  type: string;

  constructor(name: string, type: string) {
    this.name = name;
    this.type = type;
  }
}

让我们修改我们的类:Developer

class Developer {
  static develop(app: App) {
    return { name: app.name, type: app.type }; // output the same
  }
}

现在我将创建一个实例并使用参数对象调用:App Developer.develop()

const app = new App('whatsapp', 'mobile');
Developer.develop(app);
// outputs the same: { "name": "whatsapp", "type": "mobile" } 

Developer.develop(app)并输出相同的内容。这很棒,但第二种方法更具可读性和灵活性。Developer.develop({ name: 'whatsapp', type: 'mobile' })

另外,我们可以检查参数的类型。要做到这一点,我们需要创建一个对象。

首先,我将把类更改为具有以下代码的接口:App

interface App {
  name: string
  type: string
}

class Developer {
  static develop(app: App) {
    return { name: app.name, type: app.type }; 
  }
}

在上面的代码中,我们没有更改类的主体,也没有创建 的实例,但结果是相同的。在这种情况下,我们节省了大量的时间和代码键入。Developer App

结论

我们什么时候应该使用类和接口?如果要创建和传递类型检查类对象,则应使用 TypeScript 类。如果不创建对象,则接口最适合使用。