class Container {} class Bottle : Container {} class Can : Container {} class Tool {} class Corkscrew : Tool {} class CanOpener : Tool {} void open(virtual!Container, covariant!Tool); @method void _open(Bottle bottle, Corkscrew corkscrew) {} // 1 @method void _open(Can can, CanOpener opener) {} // 2 // ... Container container = new Bottle(); Tool tool = new Corkscrew(); open(container, tool); // override #1 is selected based solely on first argument's type // second argument is cast to Corkscrew // The following is illegal: Tool wrongTool = new CanOpener(); open(container, wrongTool); // override #1 is called but is passed a CanOpener.
Mark a parameter as covariant.
Marking a parameter as covariant makes it possible to override a method with an override that has a type-compatible parameter in the same position. Covariant parameters are not taken into account for override selection. The arguments passed in covariant parameters are automatically cast to the types required by the override.
covariant is useful when it is known for certain that the overrides will always be called with arguments of the required type. This can help improve performance and reduce the size of method dispatch tables.