メソッドのオーバーライド
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 38/110。
method のオーバーライドは、子 class が parent class にすでに存在する method の独自の実装を提供するときに発生します。これにより、サブクラスは同じ method シグネチャを維持しながら、継承した動作をカスタマイズできます。
子クラスで、親クラスのメソッドと同じ名前およびパラメーターを持つメソッドを定義すると、子クラスのバージョンが優先されます。
class Animal {
String name;
Animal(this.name);
void speak() {
print('$name makes a sound');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void speak() {
print('$name barks: Woof!');
}
}
void main() {
var animal = Animal('Generic');
var dog = Dog('Buddy');
animal.speak(); // Generic が音を出します
dog.speak(); // Buddy が吠えます: ワン!
}speak()をDogインスタンスに対して呼び出すと、DartはAnimalのバージョンではなく、Dogのバージョンを実行します。子クラスはparentのmethodをオーバーライドしています。
super とオーバーライドを組み合わせて、parent の動作を置き換えるのではなく拡張することもできます。
class Cat extends Animal {
Cat(String name) : super(name);
void speak() {
super.speak(); // まず親のバージョンを呼び出す
print('$name also purrs');
}
}このパターンを使うと、既存の機能を基盤にして構築できます。重要なルールはシンプルです。子クラスの同じメソッド名とパラメーターが、子クラスのインスタンスで呼び出されたときに親クラスの実装を置き換えます。
チャレンジ
簡単親のmethodを子classがoverrideして動作をカスタマイズする方法を示すnotification systemを作成しましょう。それぞれ独自の方法でmessageを届ける、異なるnotification typeを作成します。
コードを2つのファイルに整理します。
notification.dart: ここでnotification階層をDefineします。Notificationclass(parent)には、String titleとString messageを持たせます。両方の値を受け取るconstructorと、Notification: [title] - [message]をPrintするsend()methodを含めます。EmailNotificationclassはNotificationをextendsし、String recipientpropertyを追加します。send()methodをOverrideして、Sending email to [recipient]: [title] - [message]をPrintします。PushNotificationclassはNotificationをextendsし、String deviceIdpropertyを追加します。send()methodをOverrideし、まずsuperを使用してparentのsend()をCallし、その次のlineでPushed to device: [deviceId]をPrintします。
main.dart: notification fileをimportし、method overridingの動作を示します。- titleが
'Alert'、messageが'System update available'のbaseNotificationをCreateします。 - その
send()methodをCallします。 - empty lineをPrintします。
- titleが
'Welcome'、messageが'Thanks for signing up!'、recipientが'user@example.com'のEmailNotificationをCreateします。 - その
send()methodをCallします。 - empty lineをPrintします。
- titleが
'Reminder'、messageが'Meeting in 10 minutes'、deviceIdが'DEVICE-001'のPushNotificationをCreateします。 - その
send()methodをCallします。
- titleが
EmailNotificationがparentの動作を完全に置き換えている一方、PushNotificationは最初にsuper.send()をCallすることで動作を拡張していることに注目してください。どちらのアプローチも、必要に応じてmethodをOverrideする有効な方法です。
期待される出力:
Notification: Alert - System update available
Sending email to user@example.com: Welcome - Thanks for signing up!
Notification: Reminder - Meeting in 10 minutes
Pushed to device: DEVICE-001自分で試してみよう
import 'notification.dart';
void main() {
// TODO: Create a base Notification with title 'Alert' and message 'System update available'
// その send() メソッドを呼び出す
// TODO: 空行を出力する
// TODO: EmailNotification を次の内容で作成する:
// - title: 'Welcome'
// - message: 'Thanks for signing up!'
// - recipient: 'user@example.com'
// その send() メソッドを呼び出す
// TODO: 空行を出力する
// TODO: PushNotification を次の内容で作成する:
// - title: 'Reminder'
// - message: 'Meeting in 10 minutes'
// - deviceId: 'DEVICE-001'
// その send() メソッドを呼び出す
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ自分で練習してみよう: Dartオンラインコンパイラ