Слышали про
covariant? Как показывает практика, многие о нем слышали, но не до конца понимают, для чего он нужен. Разберемся!C
ovariant — это ключевое слово, которое используется для параметров методов. Оно разрешает переопределяющему методу в наследнике сузить тип параметра, указать более конкретный. Разберем на примере. У нас есть класс
Vehicle. Создадим классы более конкретного транспорта — Car и Bike.
class Vehicle {}
class Car extends Vehicle {}
class Bike extends Vehicle {}
Теперь создадим класс
Human, который будет реализовывать метод drive c определенным переданным объектом Vehicle.
class Human {
void drive(Vehicle vehicle) {}
}
В таком случае, когда мы захотим создать наследника
Human — Driver, мы не сможем уточнить класс транспорта в параметрах drive. Нам придется сделать так:
class Driver extends Human {
@override
void drive(Vehicle vehicle) {} // правильный вариант
@override
void drive(Car vehicle) // вызовет ошибку переопределения
}
И здесь нам на помощь придет
covariant. Чтобы он работал, метод drive класса Human нужно видоизменить.
class Human {
void drive(covariant Vehicle vehicle) {}
}
Теперь в реализации
Driver легко можно уточнить, какой конкретный тип требуется передать при вызове метода.
class Driver extends Human {
@override
void drive(Car vehicle) {}
}
В таком случае метод
drive у Driver принимает только Car, и попытка передать Bike приведет к ошибке типов.
void main() {
final car = Car();
final bike = Bike();
final driver = Driver();
driver.drive(bike); // ошибка argument_type_not_assignable
driver.drive(car); // верное использование
}
❤️ — если было полезно