什么时候在Dart中使用接口?

sni*_*tko 8 inheritance interface dart

我正在阅读Dart的文档,我有点困惑,也许是因为我来自Ruby,关于如何使用接口.当然,接口不是Dart独有的,当有人应该使用接口时,有很多解释.这其中,例如,似乎是说,当你在一个团队是接口仅仅是有用的.它甚至应该在开源世界中意味着什么,每个人都在阅读和重用其他人的代码?

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

  1. 在缺乏多重继承的语言中,和
  2. 就此而言,它们在某种程度上可以作为缺少多重继承的解决方法.

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

PS在相关的说明中,有没有办法在Dart中使用多重继承?

Chr*_*ett 24

更新:从Dart中删除了interface关键字.


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

采用以下(常用)示例:

interface Quackable {
  void quack();
}
Run Code Online (Sandbox Code Playgroud)

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

sayQuack(Quackable quackable) {
   quackable.quack();
}
Run Code Online (Sandbox Code Playgroud)

它允许您使用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
  }

}
Run Code Online (Sandbox Code Playgroud)

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

sayQuack(new EnterpriseDuck());
sayQuack(new MockDuck());
Run Code Online (Sandbox Code Playgroud)

我在构建使用某些"企业鸭"的解决方案时,一直在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
Run Code Online (Sandbox Code Playgroud)

所有类都是接口

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

例如,假设以下企业库:

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

sayQuack(EnterpriseDuck duck) {  // takes an instance of the EnterpriseDuck class
  duck.quack();
}
Run Code Online (Sandbox Code Playgroud)

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

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

多重继承

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

class MultiDuck implements Quackable, EnterpriseDuck, Swimable {
  // snip...
}
Run Code Online (Sandbox Code Playgroud)

接口可以有默认类

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

List myList = new List();
Run Code Online (Sandbox Code Playgroud)

您实际上正在使用List接口,new关键字从接口重定向到基础默认List实现.

关于在团队中发展

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

希望有所帮助!

  • 请考虑更新此问题,或在此帖子中添加评论,说明Dart中不再使用interface关键字. (6认同)
  • 非常感谢克里斯,这正是我所需要的.此外,示例中的类名是可爱的. (2认同)