Mixins

On occasion, the usual subclass and interface approach to classes is not quite right. One such case occurs so often that Dart supports it directly in the language: mixins. The purpose of mixins is to augment subclassing with additional behavior. This additional behavior is typically something that we will want to reuse in other classes as well.

Consider two simple classes, Person and Animal:

classes/mixins.dart
 
class​ Person {
 
String name;
 
Person(​this​.name);
 
}
 
 
class​ Animal {
 
String name;
 
Animal(​this​.name);
 
}

These two classes are unrelated to each other, though they do share a common name property.

During the course of working with these classes, we decide that we need subclasses of both. The Friend class will extend Person to represent a person with a more intimate relationship. Similarly, the Pet class will extend Animal to encapsulate an animal to which a person might have a special bond.

In both cases, the intimate nature of an implied relationship suggests that we want to be able to warmly greet a Friend or Pet. The greeting will be identical except for the name (“Howdy Alice!” “Howdy Snoopy!”). So the question becomes how do we add this common functionality without duplicating code?

The answer, of course, is with mixins. A mixin is declared as an abstract class. The class is abstract because the class into which it gets mixed will supply some vital information or behavior. In the case of our friends and pets, the corresponding classes will supply the name.

 
abstract​ ​class​ Greeting {
 
String ​get​ name;
 
greet() => ​"Howdy $name!"​;
 
}

Our greet method is fully defined, but the name getter method is left abstract by virtue of being declared without a method body. Both Person and Animal already define this getter by way of a name instance variable. In other words, Greeting is ready to mix in with both classes.

The syntax for mixins works with the extends keyword. In Dart, we say that a class extends another with a mixin. So Friend extends Person with Greeting. Pet extends Animal with the same Greeting mixin.

 
class​ Friend ​extends​ Person with Greeting {
 
Friend(name): ​super​(name);
 
}
 
 
class​ Pet ​extends​ Animal with Greeting {
 
Pet(name): ​super​(name);
 
}

That’s all there is to it. Both the Friend and Pet classes now have Greeting’s greet method available for use:

 
var​ say_hi = ​new​ Friend(​'Alice'​).greet();
 
// => 'Howdy Alice!'
 
var​ say_hi = ​new​ Pet(​'Snoopy'​).greet();
 
// => 'Howdy Snoopy!'

Dart expects mixins to work with subclasses. It is possible to mix in traits to top-level classes. In such cases, we would have to extend Object with the mixin. If that seems a little awkward, this is Dart’s way of telling us that we might be better off using a subclass in such cases.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.68.18