何时使用 Dart 中的接口?

2024-03-23

我正在阅读 Dart 的文档,对于如何使用接口,我有点困惑,也许是因为我来自 Ruby。当然,接口并不是 Dart 所独有的,关于何时应该使用接口有很多解释。This one https://stackoverflow.com/questions/1686174/when-should-one-use-interfaces例如,似乎是在说界面只有当你在团队中时才有用。在每个人都阅读和重用别人的代码的开源世界中,它到底意味着什么?

我见过的一个有趣的解释似乎暗示使用了接口:

  1. 在缺乏多重继承的语言中,以及
  2. 就此而言,它们以某种方式充当了缺乏多重继承的解决方法。

我不明白。我知道 Ruby 中的模块是一种解决方法,因为它们允许我用实际的主体定义真正的方法。接口只允许我定义实现它的类应该具有哪些方法。有什么问题吗?谁能告诉我一个真正有用的例子,我可以立即看到使用接口的价值?

附:与此相关的是,有没有办法在 Dart 中使用多重继承?


Update: 此后,interface 关键字已从 Dart 中删除 https://stackoverflow.com/a/28595665/712173.


接口很有用,因为它们允许您切换类的实现,同时仍然允许验证传入的类型是否满足接口的要求。

采取以下(经常使用的)示例:

interface Quackable {
  void quack();
}

这定义了将传递给方法的类的要求,例如:

sayQuack(Quackable quackable) {
   quackable.quack();
}

它允许您使用 Quackable 对象的任何实现,例如:

class MockDuck implements Quackable {
  void quack() => print("quack");
}

class EnterpriseDuck implements Quackable {
  void quack() {
    // connect to three enterprise "ponds"
    // and eat some server bread
    // and say "quack" using an messaging system
  }

}

这两种实现都可以与 sayQuack() 函数一起使用,但其中一种实现比另一种需要的基础设施要少得多。

sayQuack(new EnterpriseDuck());
sayQuack(new MockDuck());

在构建利用某些“企业鸭子”的解决方案时,我在 Java 世界中一直使用这种模式。在本地开发时,我只需要能够调用 sayQuack() 函数并返回一些硬编码的模拟数据。

鸭子打字

因为 Dart 是可选类型的,所以您实际上不需要使用接口,只需编写一个包含正确方法签名的类即可(尽管工具无法验证它)。

class Person {   // note: no implements keyword
  void quack() => "I'm not a duck";
}

sayQuack(new Person()); // provides the quack method, so this will still work

所有类都是接口

最后,所有类也是接口。这意味着即使第三方系统可能是在不使用接口的情况下编写的,您仍然可以使用具体类,就像它是接口一样。

例如,想象一下以下企业库:

class EnterpriseDuck { // note: no implements keyword
  void quack() {
    // snip
  }
}

sayQuack(EnterpriseDuck duck) {  // takes an instance of the EnterpriseDuck class
  duck.quack();
}

并且您希望以类型检查器可以验证的方式将模拟鸭传递到 sayQuack 方法中。您可以创建您的mockDuck来实现EnterpriseDuck隐含的接口,只需使用EnterpriseDuck作为接口即可:

class MockDuck implements EnterpriseDuck {
  void quack() => "I'm a mock enterprise duck";
}

多重继承

就多重继承而言,这在 Dart 中是不可能的。但是,您可以实现多个接口并提供您自己的所需方法的实现,例如:

class MultiDuck implements Quackable, EnterpriseDuck, Swimable {
  // snip...
}

接口可以有默认类

当你使用 Dart 时,你会发现大多数“类”实际上是接口。 List、String 等...都是提供默认实现的接口。你打电话时

List myList = new List();

您实际上正在使用 List 接口,并且 new 关键字从接口重定向到底层默认 List 实现。

关于团队发展

接口在团队开发中非常有用,即使在开源世界中也是如此。该接口定义了您应该构建的方法和属性,以便您的组件可以与我的组件一起工作。您可以构建您自己的该接口的测试实现,我可以构建该接口的具体实现,当我们都完成后,我们可以集成。如果没有发布的共享接口,我需要提供具体的实现,然后您才能真正开始。

希望有帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

何时使用 Dart 中的接口? 的相关文章

随机推荐

  • FPDF 和欧元符号的问题

    我花了几天时间筛选各种方法来鼓励 FPDF 渲染欧元符号 但没有成功 我有 currency iconv UTF 8 ISO 8859 1 TRANSLIT 结果是 iconv function iconv 检测到不完整的多字节字符 在输入
  • 在滚动视图上拖动视图:收到touchesBegan,但未收到touchesEnded 或touchesCancelled

    作为一名 iOS 编程新手 我正在努力解决iPhone 上的文字游戏 https github com afarber ios newbie tree master ScrollContent 应用程序结构是 scrollView gt c
  • 如何设置dropdownlist高度以及如何显示dropdownlist列表始终向下显示

    如何在 C 中设置下拉列表控件的高度 我尝试了这个 但它不起作用 cbo Attributes Add style height 50 而且 如何确保下拉列表的列表始终向下而不是向上 终于我明白了 cbo Height new Unit 2
  • Python - 读取 Emoji Unicode 字符

    我有一个 Python 2 7 程序 它从 SQLite 数据库读取 iOS 文本消息 文本消息是 unicode 字符串 在下面的短信中 u that u2019s U0001f63b 撇号表示为 u2019 但表情符号由 U0001f6
  • 具有 GIT 支持的 PL/SQL IDE

    我目前正在为我的公司开发 PL SQL 存储过程 我想使用代码修订控制系统来跟踪我和其他开发人员所做的更改 我喜欢 GIT 的所有优点 包括分布式 scm 功能 有没有支持GIT的PL SQL开发IDE 目前 我正在使用 JDevelope
  • 从 C# 调用非托管函数:我应该传递 StringBuilder 还是使用不安全代码?

    我有一个 C 程序 需要将字符缓冲区传递给非托管函数 我发现了两种似乎可靠的方法 但我不确定应该选择哪一种 这是非托管函数的签名 extern C declspec dllexport int getNextResponse char bu
  • 关于 C++ 中异常的缺点

    我正在阅读 Google C 风格指南 并在其中感到困惑例外情况 http google styleguide googlecode com svn trunk cppguide xml showone Exceptions Excepti
  • XPath 中“//”和“/”的区别?

    我正在尝试使用 python selenium 的 XPath I used 这个链接 http www jetairways com EN SG Home aspx尝试教程中的一些 XPath 所以我尝试了 XPath 的这两种变体 这个
  • Vuejs 刷新时路由重定向

    当我在浏览器中使用刷新按钮或点击f5在键盘上 它不会刷新我的页面 而是重定向到主页 Code router js import Vue from vue import VueRouter from vue router import sto
  • 接口依赖关系[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 当您创建一个接口并且知道您将依赖另一个接口时 您是否会将构造函数作为接口的一部分 就我而言 我想创建 我可以向客户端提供一个 IClientRe
  • 伊莎贝尔案例分析

    如何在伊莎贝尔中应用案例分析 我正在寻找类似的东西apply induct x 用于归纳 案例分析通常是通过cases方法 另见索引中的 案例 方法 伊莎贝尔 伊萨尔参考手册 http isabelle in tum de website
  • 使用 grep 列出目录中的条目

    我试图列出目录中名称仅包含大写字母的所有条目 目录需要附加 bin bash cd testfiles ls grep r 由于 grep 默认情况下仅查找大写字母 对吗 因此我只是在 testfiles 下的目录中递归搜索仅包含大写字母的
  • 将 nlog 中的记录添加到 dataType = date 的字段

    I use nlogdll 写入数据库 Oracle 与实体框架在行中 logger Log logLevel try 我在 nlog 日志中收到以下错误 文字与模板字符串不匹配 代码是 SetPropGDC LogEntity NLog
  • 在 Windows 上使用 Xerces 3.0.1 和 C++ 编写 XML

    我编写了以下函数来使用 Xerces 3 0 1 创建 XML 文件 如果我使用 foo xml 或 foo xml 的文件路径调用此函数 它会很好用 但如果我传入 c foo xml 然后我在这一行得到一个异常 XMLFormatTarg
  • C#通过OLEDB从Excel中提取格式化文本

    我正在从一个大的数据中读取数据excel已格式化文本的文件 我将数据提取到DataTable对象通过oleDBConnection GetOleDbSchemaTable 但提取的数据不包含任何格式化信息 我的要求是 我只需要提取非删除线文
  • 如何使用 Android Gradle 插件 0.7 配置 NDK

    新的 Android gradle 插件 0 7 似乎包含了对 NDK 的新支持 但在文档中几乎没有提到它 我找到的唯一参考是一个名为ndkSanAngeles https android googlesource com platform
  • 优化 Excel 公式 - SUMPRODUCT 与 SUMIFS/COUNTIFS

    根据一些网站的说法 SUMIFS 和 COUNTIFS 比 SUMPRODUCT 更快 例如 http exceluser com blog 483 excels sumifs or sumproduct which is faster h
  • 用于提供静态内容的 Servlet

    我在两个不同的容器 Tomcat 和 Jetty 上部署了一个 web 应用程序 但它们用于提供静态内容的默认 servlet 有不同的方式来处理我想要使用的 URL 结构 details http issues apache org bu
  • 除主活动外,其他活动中没有应用栏和抽屉

    主要活动 public class MainActivity extends AppCompatActivity Override protected void onCreate Bundle savedInstanceState supe
  • 何时使用 Dart 中的接口?

    我正在阅读 Dart 的文档 对于如何使用接口 我有点困惑 也许是因为我来自 Ruby 当然 接口并不是 Dart 所独有的 关于何时应该使用接口有很多解释 This one https stackoverflow com question