Covariant 키워드
Coddy Dart 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 110개 중 61번째.
서브클래스에서 메서드를 오버라이드할 때, Dart는 보통 매개변수 타입이 정확히 일치할 것을 요구합니다. 하지만 때로는 서브클래스 메서드가 부모보다 더 구체적인 타입을 받아들이도록 하고 싶을 때가 있습니다. covariant 키워드는 이를 가능하게 합니다.
Animal 클래스가 다른 Animal을 인자로 받는 메서드를 가지고 있는 시나리오를 생각해 봅시다:
class Animal {
void chase(Animal other) {
print('Chasing an animal');
}
}
class Dog extends Animal {
@override
void chase(covariant Dog other) {
print('Dog chasing another dog');
}
}covariant가 없으면, Dart는 Dog가 Animal과 같은 타입이 아니라고 오류를 발생시킬 것입니다. 매개변수 앞에 covariant를 추가함으로써, Dart에게 "이것이 더 구체적이라는 것을 알고 있으며, 올바른 타입만 전달되도록 보장하겠습니다"라고 알려주는 것입니다.
이는 하위 클래스가 논리적으로 자신의 종류와만 작업해야 할 때 유용합니다:
void main() {
Dog dog1 = Dog();
Dog dog2 = Dog();
dog1.chase(dog2); // 작동함: 다른 개를 쫓는 개
}하지만 주의하세요 - covariant를 사용하면 타입 안전성이 런타임으로 옮겨집니다. 잘못된 타입의 부모 참조를 통해 메서드를 호출하면 컴파일 타임 에러 대신 런타임 에러가 발생하게 됩니다. 전달되는 타입에 대해 확신이 있을 때만 사용하세요.
챌린지
쉬움covariant 키워드를 사용하여 반려동물이 자신의 종하고만 놀 수 있도록 보장하는 반려동물 호환성 시스템을 구축해 보겠습니다. 각 유형이 동일한 유형의 반려동물만 허용하는 playWith 메서드를 갖는 반려동물 계층 구조를 만들 것입니다.
코드를 두 개의 파일로 구성합니다:
pets.dart: 여기에 반려동물 계층 구조를 정의합니다:String name속성과 생성자를 가진Pet클래스.[name] plays with [other.name]을 출력하는playWith(Pet other)메서드를 포함합니다.Pet을 상속받고covariant키워드를 사용하여Cat만 허용하도록playWith를 오버라이드하는Cat클래스.[name] and [other.name] chase yarn together를 출력해야 합니다.Pet을 상속받고covariant키워드를 사용하여Dog만 허용하도록playWith를 오버라이드하는Dog클래스.[name] and [other.name] fetch the ball together를 출력해야 합니다.Pet을 상속받고covariant키워드를 사용하여Rabbit만 허용하도록playWith를 오버라이드하는Rabbit클래스.[name] and [other.name] hop around together를 출력해야 합니다.
main.dart: 반려동물 파일을 임포트하고 각 반려동물 유형이 자신의 종하고만 노는 방식을 보여줍니다:'Whiskers'와'Mittens'라는 이름의 두Cat객체를 생성한 다음, Whiskers가 Mittens와 놀게 합니다.'Buddy'와'Max'라는 이름의 두Dog객체를 생성한 다음, Buddy가 Max와 놀게 합니다.'Flopsy'와'Cotton'이라는 이름의 두Rabbit객체를 생성한 다음, Flopsy가 Cotton과 놀게 합니다.
covariant 키워드를 사용하면 각 서브클래스가 매개변수 유형을 Pet에서 특정 유형으로 좁힐 수 있어, 동일한 종류의 반려동물 간의 유형 안전(type-safe) 상호작용을 보장할 수 있습니다.
예상 출력:
Whiskers and Mittens chase yarn together
Buddy and Max fetch the ball together
Flopsy and Cotton hop around together치트 시트
covariant 키워드를 사용하면 서브클래스에서 부모 클래스보다 더 구체적인 매개변수 타입을 사용하여 메서드를 오버라이드할 수 있습니다.
covariant가 없으면 Dart는 메서드를 오버라이드할 때 매개변수 타입이 정확히 일치해야 합니다. covariant를 사용하면 서브클래스에서 매개변수 타입을 좁힐 수 있습니다:
class Animal {
void chase(Animal other) {
print('Chasing an animal');
}
}
class Dog extends Animal {
@override
void chase(covariant Dog other) {
print('Dog chasing another dog');
}
}이는 서브클래스가 자신의 타입하고만 작동해야 할 때 유용합니다:
void main() {
Dog dog1 = Dog();
Dog dog2 = Dog();
dog1.chase(dog2); // 작동함: Dog chasing another dog
}중요: covariant를 사용하면 타입 안전성이 컴파일 타임에서 런타임으로 이동합니다. 부모 참조를 통해 잘못된 타입으로 메서드를 호출하면 컴파일 타임 에러 대신 런타임 에러가 발생합니다.
직접 해보기
import 'pets.dart';
void main() {
// TODO: 'Whiskers'와 'Mittens'라는 이름의 Cat 객체 두 개를 생성하세요
// 그 다음 Whiskers가 Mittens와 놀게 하세요
// TODO: 'Buddy'와 'Max'라는 이름의 Dog 객체 두 개를 생성하세요
// 그 다음 Buddy가 Max와 놀게 하세요
// TODO: 'Flopsy'와 'Cotton'이라는 이름의 Rabbit 객체 두 개를 생성하세요
// 그 다음 Flopsy가 Cotton과 놀게 하세요
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.