When to use mixins and when to use interfaces in Dart?

后端 未结 6 1954
眼角桃花
眼角桃花 2020-12-07 19:28

I\'m very familiar with the concepts of interfaces and abstract classes, but not super familiar with the concepts of mixins.

Right now, in Dart, every clas

6条回答
  •  既然无缘
    2020-12-07 19:37

    Languages such as Java and C# use interfaces to have multiple inheritance of type in lieu of multiple implementation inheritance. There are complexity tradeoffs that languages with multiple implementation inheritance (such as Eiffel, C++, or Dart) have to deal with that the designers of Java and C# chose to avoid.

    However, once you have multiple implementation inheritance, there is no real need to separately support multiple interface inheritance, as an interface then becomes just a special case of an abstract class with no instance variables and only abstract methods and interface inheritance is the same as inheriting from such a class.

    Example:

    abstract class IntA {
      void alpha();
    }
    
    abstract class IntB {
      void beta();
    }
    
    class C extends IntA with IntB {
      void alpha() => print("alpha");
      void beta() => print("beta");
    }
    
    void main() {
      var c = new C();
      IntA a = c;
      IntB b = c;
      a.alpha();
      b.beta();
    }
    

    Dart has multiple implementation inheritance (via mixins), so it doesn't also need multiple interface inheritance as a separate concept, nor a way to separately define interfaces as standalone entities. Implicit interfaces (via the implements clause) are used to be able to document or verify that one class implements at least the same interface as another. For example, Int8List implements List, although the underlying implementation is completely different.

    Use of inheritance/mixins and implicit interfaces obtained through implements is generally orthogonal; you will most likely use them in conjunction rather than in lieu of one another. For example, you may want to use implements Set to describe the desired interface of a bitset implementation, and then use extends and/or with clauses to pull in the actual implementation for that interface. The reason is that your bitset will not share any of the actual implementation with Set, but you still want to be able to use them interchangeably.

    The collection library provides a SetMixin mixin for us that only requires us to implement some basic routines ourselves and supplies the rest of the Set implementation based on those.

    import "dart:collection";
    
    class BitSetImpl {
      void add(int e) { ...; }
      void remove(int e) { ...; }
      bool contains(int e) { ...; }
      int lookup(int e) { ...; }
      Iterator get iterator { ...; }
      int get length { ...; }
    }
    
    class BitSet extends BitSetImpl with SetMixin implements Set {
      BitSet() { ...; }
      Set toSet() { return this; }
    }
    

提交回复
热议问题