@override 어노테이션
Coddy Dart 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 110개 중 39번째.
@override 어노테이션은 부모 클래스의 메서드를 의도적으로 재정의하고 있음을 Dart(및 다른 개발자들)에게 알리는 권장 사항(best practice) 마커입니다. 메서드 오버라이딩은 이 어노테이션 없이도 작동하지만, @override를 사용하면 중요한 안전 장치가 추가됩니다.
class Animal {
String name;
Animal(this.name);
void speak() {
print('$name makes a sound');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
@override
void speak() {
print('$name barks: Woof!');
}
}이 어노테이션은 두 가지 주요 이점을 제공합니다. 첫째, 의도를 명확하게 문서화합니다. 코드를 읽는 사람은 누구나 이 메서드가 부모 클래스에 존재한다는 것을 즉시 알 수 있습니다. 둘째, 부모 메서드가 실제로 존재하지 않는 경우 Dart 분석기(analyzer)가 경고를 표시하여 오타나 리팩토링 실수를 조기에 발견할 수 있도록 도와줍니다.
@override 없이 메서드 이름을 잘못 입력하면 어떤 일이 발생하는지 생각해 보세요:
class Cat extends Animal {
Cat(String name) : super(name);
void speek() { // 오타! @override가 없으면 경고가 발생하지 않습니다
print('$name meows');
}
}어노테이션이 없으면 Dart는 사용자가 speek()라는 이름의 새로운 메서드를 생성한다고 가정합니다. @override를 사용하면 분석기는 부모 클래스에 해당 메서드가 존재하지 않는다는 것을 즉시 알립니다. 이 간단한 어노테이션은 나중에 찾아내기 어려울 수 있는 미묘한 버그를 방지합니다.
챌린지
쉬움상속된 동작을 커스터마이징할 때 @override 어노테이션의 중요성을 보여주는 미디어 플레이어 시스템을 구축해 보겠습니다. 각기 다른 방식으로 콘텐츠를 재생하는 다양한 미디어 유형을 만들 것입니다.
코드를 두 개의 파일로 구성합니다:
media.dart: 여기에 미디어 계층 구조를 정의합니다:String title속성, title을 매개변수로 받는 생성자, 그리고Playing: [title]을 출력하는play()메서드를 가진Media클래스Media를 확장하고String artist속성을 추가한Song클래스.@override어노테이션을 사용하고play()를 오버라이드하여Playing song: [title] by [artist]를 출력합니다.Media를 확장하고int duration속성(초 단위)을 추가한Video클래스.@override를 사용하고play()를 오버라이드하여 먼저super.play()로 부모 버전을 호출한 다음,Duration: [duration] seconds를 출력합니다.
main.dart: 미디어 파일을 임포트하고 오버라이드된 메서드들을 시연합니다:- title이
'Generic Content'인Media객체를 생성하고play()를 호출합니다. - 빈 줄을 출력합니다.
- title이
'Imagine'이고 artist가'John Lennon'인Song을 생성한 후play()를 호출합니다. - 빈 줄을 출력합니다.
- title이
'Dart Tutorial'이고 duration이360인Video를 생성한 후play()를 호출합니다.
- title이
@override 어노테이션은 개발자의 의도를 문서화하고 오류를 잡는 데 도움이 됩니다. 만약 실수로 play()를 plya()로 잘못 입력했다면, 어노테이션은 부모 클래스에 그런 메서드가 존재하지 않는다는 것을 알려줄 것입니다.
예상 출력:
Playing: Generic Content
Playing song: Imagine by John Lennon
Playing: Dart Tutorial
Duration: 360 seconds치트 시트
@override 어노테이션은 부모 클래스의 메서드를 의도적으로 재정의하는 메서드임을 표시합니다. 선택 사항이지만, 안전성과 명확성을 제공합니다.
class Animal {
String name;
Animal(this.name);
void speak() {
print('$name makes a sound');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
@override
void speak() {
print('$name barks: Woof!');
}
}@override의 장점:
- 의도를 문서화함 - 해당 메서드가 부모 클래스에 존재함을 보여줍니다.
- 오류를 포착함 - 부모 메서드가 존재하지 않을 경우 Dart 분석기가 경고를 표시하여 오타를 방지합니다.
@override가 없으면, 오타가 발생했을 때 오류를 표시하는 대신 새로운 메서드를 생성하게 됩니다:
class Cat extends Animal {
Cat(String name) : super(name);
void speek() { // 오타로 인해 경고 없이 새로운 메서드가 생성됨
print('$name meows');
}
}super를 사용하여 부모 버전을 호출할 수 있습니다:
@override
void play() {
super.play(); // 부모 메서드를 먼저 호출
print('Additional behavior');
}직접 해보기
import 'media.dart';
void main() {
// TODO: 제목이 'Generic Content'인 Media 객체를 생성하고 play()를 호출하세요
// TODO: 빈 줄을 출력하세요
// TODO: 제목이 'Imagine'이고 아티스트가 'John Lennon'인 Song을 생성한 다음 play()를 호출하세요
// TODO: 빈 줄을 출력하세요
// TODO: 제목이 'Dart Tutorial'이고 재생 시간이 360인 Video를 생성한 다음 play()를 호출하세요
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.