Menu
Coddy logo textTech

@override アノテーション

CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 39/110。

@override アノテーションは、親クラスのメソッドを意図的に置き換えていることを Dart(および他の開発者)に伝えるためのベストプラクティスマーカーです。メソッドのオーバーライドはこれなしでも機能しますが、@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!');
  }
}

このアノテーションは、2つの主要な利点を提供します。第一に、意図を明確に文書化します。コードを読む人は誰でも、このメソッドが親クラスに存在することを即座に知ることができます。第二に、親メソッドが実際には存在しない場合、Dartのアナライザーが警告を表示するため、タイポやリファクタリングのミスを早期に発見できます。

@override なしでメソッド名をスペルミスした場合に何が起こるか考えてみましょう:

class Cat extends Animal {
  Cat(String name) : super(name);
  
  void speek() {  // タイポ! @override がないと警告が表示されません
    print('$name meows');
  }
}

アノテーションがない場合、Dartはspeek()という名前の新しいメソッドを作成していると想定します。@overrideを付けると、アナライザーは親クラスにそのようなメソッドが存在しないことを即座に指摘します。このシンプルなアノテーションは、後で追跡するのが困難になる可能性のある微妙なバグを防ぎます。

challenge icon

チャレンジ

簡単

継承された動作をカスタマイズする際の @override アノテーションの重要性を示すメディアプレーヤーシステムを構築しましょう。それぞれの方法でコンテンツを再生する、異なるメディアタイプを作成します。

コードを2つのファイルに整理します:

  • media.dart: ここでメディアの階層を定義します:
    • String 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: メディアファイルをインポートし、オーバーライドされたメソッドを実演します:
    • タイトルを 'Generic Content' として Media オブジェクトを作成し、play() を呼び出します。
    • 空行を出力します。
    • タイトルを 'Imagine'、アーティストを 'John Lennon' として Song を作成し、play() を呼び出します。
    • 空行を出力します。
    • タイトルを 'Dart Tutorial'、期間を 360 として Video を作成し、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'、duration が 360 の Video を作成し、play() を呼び出す
  
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン