Inheritance from Rust’s Perspective

#![allow(unused)]
fn main() {
// Data
pub struct Data {
    id: usize,
    name: String,
}

// Concrete behavior
impl Data {
    fn new(id: usize, name: impl Into<String>) -> Self {
        Self { id, name: name.into() }
    }
}

// Abstract behavior
trait Named {
    fn name(&self) -> &str;
}

// Instanced behavior
impl Named for Data {
    fn name(&self) -> &str {
        &self.name
    }
}
}
  • From Rust’s perspective, one where Inheritance was never there, introducing inheritance would look like muddying the water between types and traits.

  • A type is a concrete piece of data and its associated behavior.

    A trait is abstract behavior that must be implemented by a type.

    A class is a combination of data, behavior, and overrides to that behavior.

  • Coming from rust, an inheritable class looks like a type that is also a trait.

  • This is not an upside, as we can no longer reason about concrete types.

  • Without being able to separate the two, it becomes difficult to reason about generic behavior vs concrete specifics, because in OOP these two concepts are tied up in each other.

  • The convenience of flat field access and DRY in type definitions is not worth the loss in specificity between writing code that delineates between behavior and data.