Mixins

  1. The need of mixins
  2. Let's say, we have Printer, Scanner and All-in-One classes. All-in-One have all functionalities of both Printer and Scanner. Like this:


    class Printer {

      void printX(doc) {

        //Print the doc

      }

    }

     

    class Scanner {

      String scanX() {

        //Scan

        String x = "Scanned";

        return x;

      }

    }

     

    class AllInOne extends Printer , Scanner{

      void showStatus() {

        print("Ready");

      }

    }


    But unfortunately, above code doesn’t run because Dart doesn’t support multiple inheritance.
    So, All-in-One can’t extend both Printer and Scanner. It has to provide its own implementation of printX and scanX. Then, there will be same method with same implementation in two different classes.

  3. Adding mixins to a class
  4. Mixins are a way of reusing a class’s code in multiple class hierarchies.

    To use a mixin, use the with keyword followed by one or more mixin names. Our example become:

    mixin Printer {

      void printX(doc) {

        //Print the doc

      }

    }

     

    mixin Scanner {

      String scanX() {

        //Scan

        String x = "Scanned";

        return x;

      }

    }

     

    class AllInOne with PrinterScanner {

      void showStatus() {

        print("Ready");

      }

    }



    Now, All-in-One is running after changing the declartion of Printer and Scanner to mixin and use with instead of extends.

    Note:

    • Mixins can't have constructors.

    • Mixins can't be instantiated.

    • Unless you want your mixin to be usable as a regular class, use the mixin keyword instead of class.


  5. Mixins restrictions
  6. Sometimes you might want to restrict the types that can use a mixin. For example, the mixin might depend on being able to invoke a method that the mixin doesn’t define. As the following example shows, you can restrict a mixin’s use by using the on keyword to specify the required superclass:


    mixin Printer on AllInOne {

      void printX(doc) {

        //Print the doc

      }

    }

     

    mixin Scanner on AllInOne {

      String scanX() {

        //Scan

        String x = "Scanned";

        return x;

      }

    }

     

    class AllInOne {

      void showStatus() {

        print("Ready");

      }

    }

     

    class CamScanner extends AllInOne with Scanner {

      //...

    }



    In the preceding code, only classes that extend or implement the AllInOne class can use the mixin Scanner. Because CamScanner extends AllInOne, CamScanner can mix in Scanner.