Menu
Coddy logo textTech

デフォルト実装のオーバーライド

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

デフォルト実装は便利ですが、標準とは異なる振る舞いが型に必要になる場合があります。その場合は、impl ブロック内で独自の実装を提供してデフォルトをoverrideできます。

同じシグネチャでメソッドを定義し、独自のロジックを含めるだけです:

trait Greet {
    fn greet(&self) -> String {
        String::from("Hello there!")
    }
}

struct Robot {
    id: u32,
}

impl Greet for Robot {
    fn greet(&self) -> String {
        format!("BEEP BOOP. Unit {} online.", self.id)
    }
}

Greet はデフォルトの greet メソッドを提供しますが、Robot はそれを独自のバージョンで完全に置き換えます。Robot に対して greet() を呼び出すと、Rust はカスタム実装を使用します:

let bot = Robot { id: 42 };
println!("{}", bot.greet());  // ビープ・ブープ。ユニット42がオンラインです。

これにより柔軟性が得られます。default で問題ない型は何も記述する必要がありません。一方、特別な動作が必要な型は、必要な method だけを override できます。それでも trait によって、実装するすべての型でその method が利用できることが保証されます。

challenge icon

チャレンジ

簡単

異なるアラートの種類がメッセージをカスタマイズできる通知システムを構築しましょう!デフォルト実装を持つトレイトを作成し、一方の型にはデフォルトを使用させ、もう一方にはカスタム動作でそれをオーバーライドさせます。

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

  • notifiable.rs:デフォルト実装を持ち、"Alert: Something happened!"を返すnotify(&self) -> Stringメソッドを持つpublicなNotifiableトレイトをDefineします。
  • alerts.rs:トレイトをそれぞれ異なる方法でimplementする、2つのpublicな構造体をCreateします。
    • GenericAlert:デフォルトのnotificationを使用するunit構造体(emptyのimpl block)
    • UrgentAlert:publicなmessageフィールド(String)を持つ構造体。デフォルトをoverrideし、{message}を返します。ここで{message}はそのstoredされたメッセージです。
  • main.rs:モジュールをまとめ、両方の動作を示します。提供されたinputを使ってGenericAlertUrgentAlertをCreateし、それらのnotificationをPrintします。

ここでの重要なポイントは、GenericAlertがデフォルトから無料で動作を得る一方、UrgentAlertはimpl block内でメソッドをDefineすることで、独自の特化されたバージョンを提供するということです。

出力は次の形式に従う必要があります。

Alert: Something happened!
URGENT: {message}

たとえば、inputがServer is down!の場合:

Alert: Something happened!
URGENT: Server is down!

inputは1つ受け取ります。urgent alertのmessageです。

自分で試してみよう

mod notifiable;
mod alerts;

use alerts::{GenericAlert, UrgentAlert};
use notifiable::Notifiable;

fn main() {
    // 緊急アラートメッセージの入力を読み取る
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let message = input.trim().to_string();

    // TODO: GenericAlert インスタンスを作成する

    // TODO: 入力メッセージで UrgentAlert インスタンスを作成する

    // TODO: GenericAlert からの通知を出力する

    // TODO: UrgentAlert からの通知を出力する
}
quiz icon腕試し

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

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

自分で練習してみよう: Rustオンラインコンパイラ