Rust 面向对象特性解析:对象、封装与继承

embedded/2025/3/5 8:26:12/

1. Rust 的对象概念

在《设计模式:可复用面向对象软件的基础》(Design Patterns: Elements of Reusable Object-Oriented Software)一书中,作者将对象定义为:

对象是数据和操作该数据的过程的封装体。

按照这个定义,Rust 通过 structenum 提供数据封装,并且可以使用 impl 块为其定义方法。因此,Rust 具备面向对象语言中的“对象”特性。

示例代码:

rust">struct Rectangle {width: u32,height: u32,
}impl Rectangle {fn area(&self) -> u32 {self.width * self.height}
}fn main() {let rect = Rectangle { width: 30, height: 50 };println!("Rectangle area: {}", rect.area());
}

在这个例子中,Rectangle 结构体包含 widthheight 两个字段,并通过 impl 块定义了 area 方法。这与 OOP 语言中的对象概念类似。

2. 封装:隐藏实现细节

封装(Encapsulation)是 OOP 的核心原则之一,它确保对象的内部状态不能被外部直接访问,而是通过公开的方法进行操作。Rust 使用 pub 关键字控制可见性。

示例代码:

rust">pub struct AveragedCollection {list: Vec<i32>,average: f64,
}impl AveragedCollection {pub fn new() -> Self {Self { list: vec![], average: 0.0 }}pub fn add(&mut self, value: i32) {self.list.push(value);self.update_average();}pub fn remove(&mut self) -> Option<i32> {let result = self.list.pop();if result.is_some() {self.update_average();}result}pub fn average(&self) -> f64 {self.average}fn update_average(&mut self) {let total: i32 = self.list.iter().sum();self.average = total as f64 / self.list.len() as f64;}
}

在这个 AveragedCollection 结构体中:

  • listaverage 字段是私有的,不能直接被外部访问。
  • 只能通过 addremoveaverage 方法来操作数据,确保 average 始终是最新的。

这种封装方式确保了对象的内部状态不会被外部代码直接修改,从而避免数据不一致的问题。

3. 继承:Rust 的替代方案

3.1 Rust 不支持传统继承

在传统的 OOP 语言(如 Java、C++)中,继承(Inheritance) 允许子类继承父类的字段和方法。然而,Rust 并不支持传统的继承,而是鼓励使用 特征(Traits)组合(Composition) 进行代码复用。

Rust 选择不支持继承的原因:

  • 减少代码耦合:继承往往导致复杂的类层次结构,使得代码难以维护。
  • 提高灵活性:通过特征和组合,可以实现更灵活的代码复用方式。

3.2 用特征(Traits)实现行为复用

在 Rust 中,可以使用 特征(Traits) 作为继承的替代方案,为不同类型定义通用行为。

rust">trait Summary {fn summarize(&self) -> String;
}struct NewsArticle {title: String,content: String,
}impl Summary for NewsArticle {fn summarize(&self) -> String {format!("{}", self.title)}
}struct Tweet {username: String,content: String,
}impl Summary for Tweet {fn summarize(&self) -> String {format!("@{}: {}", self.username, self.content)}
}fn main() {let article = NewsArticle {title: String::from("Rust 发布 1.70 版本"),content: String::from("Rust 1.70 带来了很多新特性……"),};let tweet = Tweet {username: String::from("rustlang"),content: String::from("Rust 让并发变得更简单!"),};println!("Article: {}", article.summarize());println!("Tweet: {}", tweet.summarize());
}

在这个例子中,Summary 特征提供了 summarize 方法,而 NewsArticleTweet 结构体分别实现了该特征。这种方式类似于 OOP 语言中的接口(Interface),允许不同的类型共享相同的行为。

3.3 组合(Composition)代替继承

除了特征,Rust 还鼓励使用组合(Composition) 代替继承,即通过将结构体嵌套来复用代码。

rust">struct Engine {horsepower: u32,
}struct Car {engine: Engine,brand: String,
}impl Car {fn new(brand: &str, horsepower: u32) -> Self {Self { engine: Engine { horsepower }, brand: brand.to_string() }}
}

在这个例子中,Car 结构体包含 Engine 结构体,而不是继承它。这种方式避免了继承带来的复杂性,并提高了代码的灵活性。

4. Rust 的多态(Polymorphism)

Rust 通过泛型(Generics)特征对象(Trait Objects) 来实现多态,而不是传统 OOP 语言中的类继承。

4.1 泛型

泛型允许我们编写可以适用于多种类型的代码。

rust">fn print_item<T: Summary>(item: &T) {println!("{}", item.summarize());
}

4.2 特征对象

特征对象允许在运行时进行多态调度:

rust">fn notify(item: &dyn Summary) {println!("Breaking news! {}", item.summarize());
}

&dyn Summary 允许我们传递任何实现 Summary 特征的类型。

5. 结论

Rust 采用了不同于传统 OOP 语言的方式来实现对象、封装和多态:

  • 对象:使用 structimpl
  • 封装:通过 pub 控制可见性。
  • 继承替代方案:使用 特征(Traits)组合(Composition) 代替继承。
  • 多态:使用 泛型特征对象

这些特性让 Rust 既能享受 OOP 的优点,又避免了传统 OOP 语言中的一些缺陷,使其成为现代系统编程的强大工具。


http://www.ppmy.cn/embedded/170133.html

相关文章

Python+Vue+数据可视化的考研知识共享平台(源码+论文+讲解+安装+调试+售后)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。 程序介绍 近些年来&#xff0c;科技以一种近乎狂飙突进的态势呈爆发式发展&#xff0c;成果之丰硕…

【密码学——基础理论与应用】李子臣编著 第二章 古典密码 课后习题

免责声明 这里都是自己搓或者手写的。 里面不少题目感觉有问题或者我的理解有偏颇&#xff0c;请大佬批评指正&#xff01; 不带思考抄作业的请自动退出&#xff0c;我的并非全对&#xff0c;仅仅提供思维&#xff01; 题目 2.1 def decrypt(m):s[]for i in range(len(m)):i…

Leetcode 3474. Lexicographically Smallest Generated String

Leetcode 3474. Lexicographically Smallest Generated String 1. 解题思路2. 代码实现 题目链接&#xff1a;3474. Lexicographically Smallest Generated String 1. 解题思路 这一题思路上主要就是分成两步&#xff1a; 找到所有为T的位置&#xff0c;此时其对应的位置及…

大模型在高血压预测及围手术期管理中的应用研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目的 1.3 国内外研究现状 二、大模型预测高血压的原理与方法 2.1 常用大模型介绍 2.2 数据收集与预处理 2.3 模型训练与验证 三、术前风险预测与手术方案制定 3.1 术前风险因素分析 3.2 大模型预测术前风险的方法与结果 …

HSPF 水文模型建模方法与案例分析实践技术应用

在水文模拟领域&#xff0c;HSPF 模型&#xff08;Hydrological Simulation Program Fortran&#xff09;与 SWAT 模型一样&#xff0c;都是备受瞩目的水文模型软件。HSPF 模型因其强大的功能和简便的操作&#xff0c;在全球范围内得到了广泛应用。该模型不仅能够在缺乏测量数据…

【FSM-3: 串行序列】

FSM-3&#xff1a;串行序列 1 Serial receiver FSM使用总结&#xff1a; 所有涉及输出的driver原则上用cur_sta&#xff1b;若是使用nxt_sta的相当于是提前一拍知道结果&#xff0c;所以对于输出必须要使用clocked reg&#xff0c;这样才能和cur_sta对应起来&#xff1b;描述声…

[python] del

在Python中&#xff0c; del 语句用于删除对象的引用、删除列表中的元素、删除字典中的键值对、删除类的属性等&#xff0c;以下是一些应用场景示例&#xff1a; 删除变量 python x 10 del x 上述代码删除了变量 x &#xff0c;之后再访问 x 会报错&#xff0c;因为它已从内…

通俗的方式解释“零钱兑换”问题

“零钱兑换”是一道经典的算法题目&#xff0c;其主要问题是&#xff1a;给定不同面额的硬币和一个总金额&#xff0c;求出凑成总金额所需的最少硬币个数。如果没有任何一种硬币组合能组成总金额&#xff0c;返回-1。 解题思路 动态规划&#xff1a;使用动态规划是解决零钱兑…