【Rust】——【面向对象语言的特征】

💻博主现有专栏:

                C51单片机(STC89C516),c语言,c++,离散数学,算法设计与分析,数据结构,Python,Java基础,MySQL,linux,基于HTML5的网页设计及应用,Rust(官方文档重点总结),jQuery,前端vue.js,Javaweb开发,Python机器学习等
🥏主页链接:

                Y小夜-CSDN博客

目录

🎯对象包含数据和行为

🎯封装隐藏了实现细节

🎯继承,作为系统与代码共享


        关于一个语言被称为面向对象所需的功能,在编程社区内并未达成一致意见。Rust 被很多不同的编程范式影响,包括面向对象编程;比如第十三章提到了来自函数式编程的特性。面向对象编程语言所共享的一些特性往往是对象、封装和继承。让我们看一下这每一个概念的含义以及 Rust 是否支持它们。

🎯对象包含数据和行为

它这样定义面向对象编程:

        在这个定义下,Rust 是面向对象的:结构体和枚举包含数据而 impl 块提供了在结构体和枚举之上的方法。虽然带有方法的结构体和枚举并不被 称为 对象,但是它们提供了与对象相同的功能,参考 The Gang of Four 中对象的定义。

🎯封装隐藏了实现细节

        另一个通常与面向对象编程相关的方面是 封装encapsulation)的思想:对象的实现细节不能被使用对象的代码获取到。所以唯一与对象交互的方式是通过对象提供的公有 API;使用对象的代码无法深入到对象内部并直接改变数据或者行为。封装使得改变和重构对象的内部时无需改变使用对象的代码。

        结构体也可以有一个字段,该字段保存了 vector 中所有值的平均值。这样,希望知道结构体中的 vector 的平均值的人可以随时获取它,而无需自己计算。换句话说,AveragedCollection 会为我们缓存平均值结果。

pub struct AveragedCollection {
    list: Vec<i32>,
    average: f64,
}

        注意,结构体自身被标记为 pub,这样其他代码就可以使用这个结构体,但是在结构体内部的字段仍然是私有的。这是非常重要的,因为我们希望保证变量被增加到列表或者被从列表删除时,也会同时更新平均值。

impl AveragedCollection {
    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();
        match result {
            Some(value) => {
                self.update_average();
                Some(value)
            }
            None => None,
        }
    }

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

        公有方法 addremove 和 average 是修改 AveragedCollection 实例的唯一方式。当使用 add 方法把一个元素加入到 list 或者使用 remove 方法来删除时,这些方法的实现同时会调用私有的 update_average 方法来更新 average 字段。

  list 和 average 是私有的,所以没有其他方式来使得外部的代码直接向 list 增加或者删除元素,否则 list 改变时可能会导致 average 字段不同步。average 方法返回 average 字段的值,这使得外部的代码只能读取 average 而不能修改它。

        因为我们已经封装好了 AveragedCollection 的实现细节,将来可以轻松改变类似数据结构这些方面的内容。例如,可以使用 HashSet<i32> 代替 Vec<i32> 作为 list 字段的类型。只要 addremove 和 average 公有函数的签名保持不变,使用 AveragedCollection 的代码就无需改变。相反如果使得 list 为公有,就未必都会如此了: HashSet<i32> 和 Vec<i32> 使用不同的方法增加或移除项,所以如果要想直接修改 list 的话,外部的代码可能不得不做出修改。

🎯继承,作为系统与代码共享

        继承Inheritance)是一个很多编程语言都提供的机制,一个对象可以定义为继承另一个对象定义中的元素,这使其可以获得父对象的数据和行为,而无需重新定义。

        如果一个语言必须有继承才能被称为面向对象语言的话,那么 Rust 就不是面向对象的。因为没有宏则无法定义一个结构体继承父结构体的成员和方法。

        然而,如果你过去常常在你的编程工具箱使用继承,根据你最初考虑继承的原因,Rust 也提供了其他的解决方案。

        选择继承有两个主要的原因。第一个是为了重用代码:一旦为一个类型实现了特定行为,继承可以对一个不同的类型重用这个实现。Rust 代码中可以使用默认 trait 方法实现来进行有限的共享,在示例 10-14 中我们见过在 Summary trait 上增加的 summarize 方法的默认实现。任何实现了 Summary trait 的类型都可以使用 summarize 方法而无须进一步实现。这类似于父类有一个方法的实现,而通过继承子类也拥有这个方法的实现。当实现 Summary trait 时也可以选择覆盖 summarize 的默认实现,这类似于子类覆盖从父类继承的方法实现。

        第二个使用继承的原因与类型系统有关:表现为子类型可以用于父类型被使用的地方。这也被称为 多态polymorphism),这意味着如果多种对象共享特定的属性,则可以相互替代使用。

相关推荐

  1. Rust】——【面向对象语言特征

    2024-06-08 15:42:04       32 阅读
  2. 面向对象特征

    2024-06-08 15:42:04       46 阅读
  3. 关于go和rust语言对比

    2024-06-08 15:42:04       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-08 15:42:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-08 15:42:04       101 阅读
  3. 在Django里面运行非项目文件

    2024-06-08 15:42:04       82 阅读
  4. Python语言-面向对象

    2024-06-08 15:42:04       91 阅读

热门阅读

  1. vscode找不到settings.json

    2024-06-08 15:42:04       27 阅读
  2. 【pnpm】安装依赖基础

    2024-06-08 15:42:04       32 阅读
  3. 求前缀表达式的值

    2024-06-08 15:42:04       28 阅读
  4. 深入理解 Vue 中的响应式系统

    2024-06-08 15:42:04       31 阅读
  5. Hudi Spark Sql Procedures 回滚 Hudi 表数据

    2024-06-08 15:42:04       32 阅读
  6. webrtc客户端测试和arm平台测试(待补充)

    2024-06-08 15:42:04       29 阅读
  7. 用r语言处理 Excel数据当中的缺失值方法

    2024-06-08 15:42:04       33 阅读
  8. 【Unity】资源管理与热更 YooAsset+HybridCLR

    2024-06-08 15:42:04       37 阅读
  9. 0101__linux libtool简单使用

    2024-06-08 15:42:04       32 阅读
  10. 05 Linux 内核启动流程

    2024-06-08 15:42:04       28 阅读
  11. 【GIC400】——中断使能

    2024-06-08 15:42:04       32 阅读