Ключевое слово covariant
Ключевое слово covariant применяется к параметрам методов
в классах и позволяет при переопределении метода в подклассе
сузить тип параметра до подтипа. По умолчанию в Dart параметры
методов являются контравариантными: при переопределении тип
параметра может быть только таким же или более широким.
Ключевое слово covariant снимает это ограничение и
разрешает использовать более конкретный тип. Его можно указать
как при объявлении метода в базовом классе, так и при
переопределении в подклассе.
Синтаксис
// в базовом классе
void method(covariant Type param) {}
// при переопределении в подклассе
@override
void method(covariant SubType param) {}
Пример
Давайте рассмотрим базовый класс Animal с методом
makeSound, принимающим параметр типа Animal,
и подкласс Dog, который сужает тип параметра до
Dog с помощью covariant:
class Animal
{
void makeSound(covariant Animal other)
{
print('Animal sound');
}
}
class Dog extends Animal
{
@override
void makeSound(covariant Dog other)
{
print('Dog sound');
}
}
void main()
{
Dog dog = Dog();
dog.makeSound(Dog());
}
Результат выполнения кода:
"Dog sound"
Пример
Без ключевого слова covariant попытка сузить тип
параметра привела бы к ошибке компиляции. Давайте убедимся,
что при передаче объекта несовместимого типа возникнет
ошибка времени выполнения:
class Animal
{
void makeSound(covariant Animal other)
{
print('Animal sound');
}
}
class Dog extends Animal
{
@override
void makeSound(covariant Dog other)
{
print('Dog sound');
}
}
void main()
{
Animal animal = Dog();
animal.makeSound(Animal());
}
Результат выполнения кода:
TypeError: Instance of 'Animal': type 'Animal' is not a subtype of type 'Dog'
Пример
Ключевое слово covariant также можно использовать
с обобщёнными типами. Давайте создадим класс Box,
который принимает объекты типа T, и подкласс
IntBox, сужающий тип до int:
class Box<T>
{
void put(covariant T item)
{
print('Put: $item');
}
}
class IntBox extends Box<int>
{
@override
void put(covariant int item)
{
print('Put int: $item');
}
}
void main()
{
IntBox box = IntBox();
box.put(12345);
}
Результат выполнения кода:
"Put int: 12345"
Смотрите также
-
ключевое слово
extends,
которое используется для наследования классов -
ключевое слово
operator,
которое позволяет переопределять операторы -
ключевое слово
abstract,
которое создаёт абстрактные классы -
ключевое слово
implements,
которое реализует интерфейсы