20.10 Summary
Rust offers powerful features to achieve the goals traditionally associated with Object-Oriented Programming—encapsulation, polymorphism, and code reuse—but employs a different set of tools compared to class-based languages like C++:
- Encapsulation: Achieved via modules and the visibility system (
pub
), controlling access primarily at the module boundary. Struct fields are private by default, promoting controlled access through methods. - Code Reuse: Favors composition over inheritance. Reuse is also facilitated by generics and traits with default method implementations.
- Polymorphism:
- Compile-time Polymorphism (Static Dispatch): The preferred approach in Rust, achieved through generics and trait bounds. Monomorphization yields high performance comparable to non-polymorphic code.
- Runtime Polymorphism (Dynamic Dispatch): Enabled by trait objects (
dyn Trait
). Uses fat pointers and vtables, conceptually similar to C++ virtual functions, suitable for scenarios requiring runtime flexibility or heterogeneous collections.
- Alternatives: Enums provide a robust alternative for handling closed sets of related types, offering compile-time exhaustiveness checks and often better performance than trait objects.
- Key Differences from C++ OOP: No implementation inheritance (
class Derived : public Base
), noprotected
visibility, encapsulation is module-based, strong preference for composition and compile-time polymorphism.
By combining structs, enums, impl
blocks, traits, generics, and modules, Rust provides a flexible and safe system for building abstractions and managing complexity, aiming to avoid some common pitfalls of classical inheritance while retaining the core benefits of object-oriented design principles.