Menu
Coddy logo textTech

Composition

Part of the Object Oriented Programming section of Coddy's Rust journey. Lesson 55 of 61.

Many object-oriented languages rely heavily on inheritance to share functionality between types. Rust takes a different approach: composition. Instead of inheriting behavior from a parent, you build complex types by including other types as fields.

Consider modeling a car. Rather than creating a base Vehicle class and inheriting from it, you compose a Car from smaller, focused components:

struct Engine {
    horsepower: u32,
}

struct Wheels {
    count: u8,
    diameter: f32,
}

struct Car {
    engine: Engine,
    wheels: Wheels,
    brand: String,
}

The Car doesn't inherit from Engine or Wheels. It has them. This "has-a" relationship is composition. You access the inner components through their fields and can call their methods directly:

impl Engine {
    fn start(&self) {
        println!("Engine with {} HP started!", self.horsepower);
    }
}

impl Car {
    fn start(&self) {
        self.engine.start();  // Delegate to the inner component
    }
}

This pattern keeps each struct focused on a single responsibility. Need to change how engines work? Modify only the Engine struct. Want to reuse Wheels for a motorcycle? Just include it in a new struct. Composition gives you flexibility without the tight coupling that inheritance often creates.

challenge icon

Challenge

Easy

Let's build a computer system using composition! Instead of creating one massive struct, you'll compose a Computer from smaller, focused components: a CPU and Memory. Each component will know how to describe itself, and the Computer will delegate to its parts.

You'll organize your code across three files:

  • cpu.rs: Define a public CPU struct with two public fields: cores (u32) for the number of cores, and speed_ghz (f32) for the clock speed. Add a specs method that returns a String describing the CPU in the format {cores}-core @ {speed_ghz}GHz.
  • memory.rs: Define a public Memory struct with a public field size_gb (u32) for the memory size. Add a specs method that returns a String in the format {size_gb}GB RAM.
  • main.rs: Bring in both modules and create a public Computer struct that has a cpu field of type CPU and a memory field of type Memory. Implement a system_info method on Computer that delegates to its components and prints the full system specification. Use the provided inputs to build a Computer and display its info.

The system_info method should print:

System: {cpu_specs} | {memory_specs}

For example, with inputs 8, 3.5, and 16:

System: 8-core @ 3.5GHz | 16GB RAM

And with inputs 4, 2.8, and 32:

System: 4-core @ 2.8GHz | 32GB RAM

You will receive three inputs: CPU cores (parse as u32), CPU speed (parse as f32), and memory size (parse as u32).

Try it yourself

mod cpu;
mod memory;

use cpu::CPU;
use memory::Memory;

// TODO: Define a public Computer struct with two public fields:
// - cpu: CPU
// - memory: Memory

// TODO: Implement a system_info method on Computer that:
// - Delegates to cpu.specs() and memory.specs()
// - Prints: System: {cpu_specs} | {memory_specs}

fn main() {
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let cores: u32 = input.trim().parse().expect("Invalid number");
    
    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let speed_ghz: f32 = input.trim().parse().expect("Invalid number");
    
    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let size_gb: u32 = input.trim().parse().expect("Invalid number");
    
    // TODO: Create CPU and Memory instances using the parsed inputs
    
    // TODO: Create a Computer instance with the CPU and Memory
    
    // TODO: Call system_info() on the computer to print the result
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming

Practice on your own: Online Rust compiler