Menu
CoddyTech

覆盖默认实现

本课属于 Coddy Rust 学习旅程的“面向对象编程”单元。第 32 课,共 61 课。

默认实现很方便,但有时类型需要不同于标准行为的行为。这种情况下,你可以在 impl 块中提供自己的实现,来重写默认实现。

只需定义具有相同签名的方法,并加入你自定义的逻辑:

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 号机器人已上线。

这样更灵活:适用默认行为的类型无需编写任何内容,而需要专门行为的类型可以只重写它们需要的方法。这个 trait 仍能保证每个实现它的类型都拥有该方法。

challenge icon

挑战

简单

让我们构建一个通知系统,让不同类型的警报可以自定义消息!你将创建一个带默认实现的 trait,然后让一种类型使用默认实现,另一种类型通过自定义行为覆盖它。

你将把代码分到三个文件中:

  • notifiable.rs:定义一个公有的 Notifiable trait,其中包含一个 notify(&self) -> String 方法,该方法有一个默认实现,会返回 "Alert: Something happened!"。
  • alerts.rs:创建两个以不同方式实现该 trait 的公有结构体:
    • GenericAlert:一个使用默认通知的单元结构体(空的 impl 块)
    • UrgentAlert:一个包含公有 message 字段(String)的结构体,它会覆盖默认实现,返回 "URGENT: {message}",其中 {message} 是它存储的消息
  • main.rs:整合各个模块并演示这两种行为。使用提供的输入创建一个 GenericAlert 和一个 UrgentAlert,然后打印它们的通知。

这里的关键在于,GenericAlert 会免费获得默认行为,而 UrgentAlert 则通过在自己的 impl 块中定义该方法,提供专门的实现。

你的输出应符合以下格式:

Alert: Something happened!
URGENT: {message}

例如,输入 Server is down! 时:

Alert: Something happened!
URGENT: Server is down!

你将收到一个输入:紧急警报的消息。

亲手试试

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 在线编译器