What is covariant in Dart

What is the article about?

The covariant keyword was introduced into Dart to combat the important problem of method overriding.

The article contains an analysis of the problem, a description of how covariant works, and an example of its use to solve the problem.

Problem

If a method of a parent class is overridden in a child class, then the parameter of the child class method can be an instance only of the class that is specified in this parameter in the method of the parent class.

Thus, if in an overridden method you use a parameter of a class that is a child of the class that is specified for the parameter in the method of the inherited class, an error will occur. An example is shown in Fig. 1.

Fig.1 Example of a problem

Fig.1 Example of a problem

  • Cat is a subclass of Animal that overrides the eat method. Animal in the eat method requires a Food data type parameter.

  • Fish is a subclass of Food – i.e. implicitly, instances of the class Fish are instances of the class Food. However, if you specify a parameter with the data type Fish in Cat.eat, an error will occur.

The situation is similar with the implementation of the interface (see Fig. 2).

Fig.2 - Example with interface

Fig.2 – Example with interface

To solve this problem, Dart 2.12 introduced the covariant keyword.

What is covariant

covariant is a keyword that is used in conjunction with method parameters when child classes override methods of parent classes in order to solve the problem of child classes not being recognized when methods are overridden.

A parameter to a child method, instead of using the data type specified in the overridden parent class method, can use a data type that is a child of the parent class specified in the method. An example is shown in Fig. 3.

Fig.3 - Example of using covariant in a child class

Fig.3 – Example of using covariant in a child class

The covariant keyword tells the parser not to perform strict data type checking. However, if you use a data type for a parameter that is not a child class of the class specified for the parameter in a method of the parent class, an error will occur (see Figure 4).

Fig.4 - Example of an error

Fig.4 – Example of an error

The covariant keyword can be used in a superclass method or in a derived class method. However, it is good practice to use covariant in parent class methods to explicitly indicate in the parent class interface that child classes can change this interface. This approach also allows all child classes in a method override to change the data type for a parameter defined with covariant. An example is shown in Fig. 5.

Fig.5 - Example of using covariant in a parent class

Fig.5 – Example of using covariant in a parent class

Conclusion

The covariant keyword is useful to know, because something similar to the example presented in the article can very well occur in real life. Covariant is also often used in Flutter sources and is often asked during interviews.

Thank you for your attention!

Code from examples
class Food {}

class Animal {
  void eat(covariant Food food) {
    print('Animal eats $food');
  }
}

class Fish extends Food {}

class Cat extends Animal {
  @override
  void eat(Fish food) {
    print('Cat eats $food');
  }
}

class Meat extends Food {}

class Dog extends Animal {
  @override
  void eat(Meat food) {
    print('Dog eats $food');
  }
}

void main() {
  Food food = Food();
  Animal animal = Animal();
  animal.eat(food);

  Fish fish = Fish();
  Cat cat = Cat();
  cat.eat(fish);

  Meat meat = Meat();
  Dog dog = Dog();
  dog.eat(meat);
}

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *