Menu
Coddy logo textTech

Standardimplementierungen überschreiben

Teil des Abschnitts Objektorientierte Programmierung der Rust-Journey von Coddy. Lektion 32 von 61.

Standardimplementierungen sind praktisch, aber manchmal benötigt ein Typ ein Verhalten, das vom Standard abweicht. Wenn das passiert, kannst du den Standard überschreiben, indem du deine eigene Implementierung im impl-Block bereitstellst.

Definiere die Methode einfach mit derselben Signatur, aber füge deine eigene Logik hinzu:

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)
    }
}

Obwohl Greet eine standardmäßige greet-Methode bereitstellt, ersetzt Robot sie vollständig durch seine eigene Version. Wenn du greet() für einen Robot aufrufst, verwendet Rust die benutzerdefinierte Implementierung:

let bot = Robot { id: 42 };
println!("{}", bot.greet());  // BEEP BOOP. Einheit 42 online.

Das gibt dir Flexibilität: Typen, die mit dem Standardverhalten zufrieden sind, müssen nichts schreiben, während Typen, die ein spezialisiertes Verhalten benötigen, nur die Methoden überschreiben können, die für sie relevant sind. Das Trait garantiert weiterhin, dass jeder implementierende Typ über die Methode verfügt.

challenge icon

Aufgabe

Einfach

Erstelle ein Benachrichtigungssystem, in dem verschiedene Alarmtypen ihre Nachrichten anpassen können! Du erstellst ein Trait mit einer Standardimplementierung. Anschließend verwendet ein Typ die Standardimplementierung, während ein anderer sie mit einem eigenen Verhalten überschreibt.

Du organisierst deinen Code über drei Dateien:

  • notifiable.rs: Definiere ein öffentliches Notifiable-Trait mit einer notify(&self) -> String-Methode, die eine Standardimplementierung besitzt und "Alert: Something happened!" zurückgibt.
  • alerts.rs: Erstelle zwei öffentliche Structs, die dein Trait auf unterschiedliche Weise implementieren:
    • GenericAlert: ein Unit-Struct, das die Standardbenachrichtigung verwendet (leerer impl-Block)
    • UrgentAlert: ein Struct mit einem öffentlichen message-Feld (String), das die Standardimplementierung überschreibt und "URGENT: {message}" zurückgibt, wobei {message} die gespeicherte Nachricht ist
  • main.rs: Führe deine Module zusammen und demonstriere beide Verhaltensweisen. Erstelle mithilfe der bereitgestellten Eingabe ein GenericAlert und ein UrgentAlert und gib anschließend ihre Benachrichtigungen aus.

Die wichtigste Erkenntnis ist, dass GenericAlert dank der Standardimplementierung kostenloses Verhalten erhält, während UrgentAlert eine eigene spezialisierte Version bereitstellt, indem es die Methode in seinem impl-Block definiert.

Deine Ausgabe sollte diesem Format entsprechen:

Alert: Something happened!
URGENT: {message}

Zum Beispiel bei der Eingabe Server is down!:

Alert: Something happened!
URGENT: Server is down!

Du erhältst eine Eingabe: die Nachricht für den dringenden Alarm.

Probier es selbst

mod notifiable;
mod alerts;

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

fn main() {
    // Eingabe für die dringende Alarmmeldung lesen
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let message = input.trim().to_string();

    // TODO: Erstelle eine GenericAlert-Instanz

    // TODO: Erstelle eine UrgentAlert-Instanz mit der Eingabenachricht

    // TODO: Gib die Benachrichtigung von GenericAlert aus

    // TODO: Gib die Benachrichtigung von UrgentAlert aus
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Rust-Compiler