When to use interfaces in Dart?

I read the Darth documentation, and I was a little confused, maybe because I'm from Ruby on how to use interfaces. Of course, interfaces are not unique to Dart, and there are many explanations when you need to use an interface. This one, for example, seems to say that interfaces are only useful when you're on a team. What does this even mean in an open source world where everyone reads and reuses the code of the other?

One interesting explanation I saw seems to imply the use of interfaces:

  • in languages โ€‹โ€‹that do not have multiple inheritance, and
  • In this case, they somehow serve as a workaround for the lack of multiple inheritance.

I do not understand this. I understand that modules in Ruby are a workaround because they allow me to define real methods with real bodies. Interfaces allow me to determine which methods a class should implement. What is the catch? Can anyone talk about a real useful example where I can immediately see the meaning of using interfaces?

PS As for the related note, is there a way to use multiple inheritance in Dart?

+8
inheritance interface dart
source share
3 answers

Interfaces are useful because they allow you to switch class implementations while still checking that the type passed in meets the interface requirements.

Take the following (commonly used) example:

interface Quackable { void quack(); } 

This defines the requirements of the class that will be passed to the method, for example:

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

which allows you to use any implementation of the Quackable object, for example:

 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 } } 

Both of these implementations will work with the sayQuack () function, but significantly less infrastructure is required than the other.

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

I use this template all the time in the Java world when creating solutions that use some kind of enterprise duck. When developing locally, all I just need is to be able to call the sayQuack () function and return some hard-coded, mock data.

Duck seal

Since Dart is not necessarily printed, you actually do not need to use the interface, just writing a class that contains the correct method signature will work (although the tools will not be able to verify it).

 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 

All classes are interfaces.

Finally, all classes are also interfaces. This means that although a third-party system can be written without using interfaces, you can still use a specific class, as if it were an interface.

For example, imagine the following corporate library:

 class EnterpriseDuck { // note: no implements keyword void quack() { // snip } } sayQuack(EnterpriseDuck duck) { // takes an instance of the EnterpriseDuck class duck.quack(); } 

And you want to pass the false duck to the sayQuack method so that the validating type can validate. You can create your mockDuck to implement an interface implied by EnterpriseDuck just by using EnterpriseDuck as an interface:

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

Multiple inheritance

In terms of multiple inheritance, this is not possible in Dart. However, you can implement several interfaces and provide your own implementations of the necessary methods, for example:

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

Interfaces may have default classes.

As you use Dart, you will find that most of the โ€œclassesโ€ are actually interfaces. List, String, etc. - all interfaces with default implementation. When you call

 List myList = new List(); 

you are actually using the List interface, and the new keyword redirects from the interface to the default base list implementation.

Regarding team development

Interfaces are useful in teamwork, even in the open source world. The interface defines the methods and properties that you must create in order for your component to work with my component. You can create your own test implementation of this interface, and I can implement my specific implementation of this interface, and when we both finish, we can integrate. Without a published shared interface, I will need to provide a specific implementation before you can get started.

Hope this helps!

+19
source share

In principle, interfaces have nothing to do with multiple inheritance. When doing this, you can fake several inheritance and abuse interfaces, but if you want true multiple inheritance (or mixins or traits), then Dart does not provide them (at present - I believe that mixins will find their way some day).

What are the interfaces for? This is an explicit contract. Say that you have two components A and B that should work with each other. You can actually call B from A directly and it will work, but the next time you want to change B , you will have to watch A how it uses it. This is because B did not display an explicit interface. Yes, the correct word for interfaces is not implemented, but disclosed.

If you hide the implementation of B behind the interface and only provide that interface A , then you can change B as you wish and only worry about still exposing the same interface. An interface can even be displayed in more than one class, and the caller does not need to care (or even know).

Please note that the word interface has two meanings: a general component contract, which can also be described in a simple language in the documentation, and a special language design that will help you describe (as well as provide) some parts of a contract within a programming language.

You do not have to use the language construct, but it is considered to be a good style to use to describe the parts of the contract that the programming language allows you to use.

Now what is this contract? Simply put, a contract is a description of what a component expects from its user and what the user can expect from this component.

For example, let's say I have a method that calculates the absolute value of a number:

 class MathUtils { /// Computes absolute value of given [number], which must be a [num]. /// Return value is also a [num], which is never negative. absoluteValue(number) { ... here the implementation ... } } 

The contract here is fully described in the commentary on the documentation (well, not completely, we could also describe what the absolute value is, but this is good enough). Well ... but some parts of the comment can be expressed directly in the language, right?

 class MathUtils { /// Computes absolute value of given [number]. /// Return value is never negative. num absoluteValue(num number) { ... here the implementation ... } } 

Please note that some parts of the contract simply cannot be expressed in a programming language - here the language does not know what the absolute value is, it must be left in the comment. Furthermore, you cannot express that the return value is never negative, so it should also remain in the comment. But in fact, readers of your code know what the absolute value is (and that it is never negative), and the name of the method quite clearly indicates the goal, so the comment can be completely omitted:

 class MathUtils { num absoluteValue(num number) { ... here the implementation ... } } 

So, some parts of the contract are expressed explicitly using language means, and some parts are expressed implicitly (you rely on people who know what the absolute meaning is).

And interfaces in this language are used to remove the contract from implementation. It is probably too difficult to use in small programs, but it pays off when executing large programs (which does not require a team).

Uff, this turned out to be longer than I expected. Hope this helps.

+4
source share

Interfaces are part of the type system in Dart, and type declarations are optional. This means that interfaces are also optional.

Interfaces help document the methods your object responds to. If you implement an interface, you promise to implement all the methods in the interface.

Dart uses this information to provide warnings about type mismatch during compilation, to provide more useful hints for code support and to help with some refactoring.

+1
source share

All Articles