首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有可能定义“接口”来接受前面不知道类型/实现的类实例?

是否有可能定义“接口”来接受前面不知道类型/实现的类实例?
EN

Stack Overflow用户
提问于 2021-01-28 17:49:46
回答 1查看 129关注 0票数 0

我对飞镖很陌生。在打字稿中,我可以这样做:

代码语言:javascript
复制
// business-logic.ts

interface Item { name: string; }

interface Repository {
  addItem: (item: Item) => Promise<void>;
}

export class BusinessLogic {
  private repo: Repository;

  constructor(repo: Repository) {
    this.repo = repo;
  }

  async doSomething() {
    await this.repo.addItem({ name: 'apple' });
  }
}
代码语言:javascript
复制
// repo.ts

export class Repository {
  async addItem(item: { name: string }) { /* impl */ }
}
代码语言:javascript
复制
// runtime.ts
import { BusinessLogic } from './business-logic';
import { Repository } from './repo';

const logic = new BusinessLogic(new Repo());

因此,业务逻辑可以显式地定义它需要什么,然后可以在不交换任何类型(类型文件)的情况下完成这些依赖关系的实际实现。

我在飞镖里可能是这样的吗?或者唯一的选择是在业务逻辑中定义抽象类Repository,然后在存储库文件中导入这个抽象类并使repository类扩展它?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-28 20:45:51

JavaScript是一种动态类型的语言,而TypeScript仅仅是这种语言的开发级超集,TypeScript接口不是(也不可能)硬契约。它们只是普通JavaScript对象的脚手架,如果它们不遵守定义,那么它们就会符合抛出的编译时错误(而不是运行时错误)。

另一方面,Dart是一种强类型语言,因此接口被绑定到类定义,而不是任意对象和铁板一块的契约。因此,在使用接口之前,需要显式定义实现接口的类。

代码语言:javascript
复制
// business_logic.dart

abstract class IItem {
  String item;
}

abstract class IRepository {
  Future<void> addItem(IItem item);
}

class BusinessLogic {
  Repository _repo;

  BusinessLogic(this._repo);

  void doSomething() async {}
}

这里定义了接口以及BusinessLogic类。请注意,Dart只是为此使用抽象类,因此惯例是以"I“开头类名,以区分接口和基类。除此之外,唯一的其他区别主要是句法。

代码语言:javascript
复制
// repo.dart

class Item implements IItem {
  String item;
}

class Repository implements IRepository {
  Future<void> addItem(IItem item) async {
    /* impl */
  }
}

这里定义了实现接口的类。同样,这里的区别主要是语法,除了必须显式定义Item并必须实现IItem这一例外。

(需要注意的一点是,在TypeScript代码中,Repository类实际上并不引用RepositoryItem接口,而是定义了结构和内联类型限制,这些结构和限制恰好与它们兼容。虽然这不太可能导致运行时错误,但如果这是生产代码,则需要修复这些排版。顺便说一句,如果TypeScript是像Dart那样强类型的,那么这个错误将是一个错误。)

代码语言:javascript
复制
// runtime.dart

import './business_logic' show BusinessLogic;
import './repo' show Repository;

final logic = BusinessLogic(Repository());

这里唯一的区别是句法。注意,show语法仅仅是为了匹配来自TypeScript的选择性导入,而实际上并不是必需的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65942576

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档