Menu
Coddy logo textTech

@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를 사용하면 분석기는 부모 클래스에 해당 메서드가 존재하지 않는다는 것을 즉시 알립니다. 이 간단한 어노테이션은 나중에 찾아내기 어려울 수 있는 미묘한 버그를 방지합니다.

challenge icon

챌린지

쉬움

상속된 동작을 커스터마이징할 때 @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이 360Video를 생성한 후 play()를 호출합니다.

@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()를 호출하세요
  
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨