Menu
Coddy logo textTech

Nadpisywanie wartości domyślnych

Część sekcji Programowanie obiektowe ścieżki Rust w Coddy. Lekcja 32 z 61.

Implementacje domyślne są wygodne, ale czasami typ potrzebuje zachowania, które różni się od standardowego. W takiej sytuacji możesz nadpisać domyślną implementację, podając własną implementację w bloku impl.

Po prostu zdefiniuj metodę z tą samą sygnaturą, ale dodaj własną logikę:

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

Mimo że Greet udostępnia domyślną metodę greet, Robot całkowicie ją zastępuje własną wersją. Gdy wywołasz greet() na obiekcie Robot, Rust użyje własnej implementacji:

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

Zapewnia to elastyczność: typy, którym odpowiada domyślne zachowanie, nie muszą niczego zapisywać, a typy wymagające specjalnego działania mogą nadpisać tylko te metody, na których im zależy. Cecha nadal gwarantuje, że każda implementująca ją klasa ma tę metodę dostępną.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system powiadomień, w którym różne typy alertów mogą dostosowywać swoje komunikaty! Utworzysz cechę z domyślną implementacją, a następnie sprawisz, że jeden typ będzie korzystać z domyślnej implementacji, a drugi ją nadpisze, stosując własne zachowanie.

Rozmieścisz kod w trzech plikach:

  • notifiable.rs: Zdefiniuj publiczną cechę Notifiable z metodą notify(&self) -> String, która ma domyślną implementację zwracającą "Alert: Something happened!".
  • alerts.rs: Utwórz dwie publiczne struktury, które implementują tę cechę na różne sposoby:
    • GenericAlert: struktura jednostkowa, która używa domyślnego powiadomienia (pusty blok impl)
    • UrgentAlert: struktura z publicznym polem message (String), która nadpisuje domyślną implementację, aby zwracać "URGENT: {message}", gdzie {message} to przechowywana w niej wiadomość
  • main.rs: Połącz moduły i zademonstruj oba zachowania. Utwórz GenericAlert i UrgentAlert, używając podanego wejścia, a następnie wyświetl ich powiadomienia.

Najważniejsze jest to, że GenericAlert korzysta z domyślnego zachowania, a UrgentAlert udostępnia własną, wyspecjalizowaną wersję, definiując metodę w swoim bloku impl.

Wynik powinien mieć następujący format:

Alert: Something happened!
URGENT: {message}

Na przykład dla wejścia Server is down!:

Alert: Something happened!
URGENT: Server is down!

Otrzymasz jedno wejście: wiadomość dla pilnego alertu.

Spróbuj swoich sił

mod notifiable;
mod alerts;

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

fn main() {
    // Wczytaj dane wejściowe dla pilnego alertu
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let message = input.trim().to_string();

    // TODO: Utwórz instancję GenericAlert

    // TODO: Utwórz instancję UrgentAlert z wiadomością podaną na wejściu

    // TODO: Wyświetl powiadomienie z GenericAlert

    // TODO: Wyświetl powiadomienie z UrgentAlert
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Rust online