Menu
CoddyTech

Kết hợp

Thuộc phần Lập trình hướng đối tượng trong hành trình Rust của Coddy. Bài học 55 trên 61.

Nhiều ngôn ngữ lập trình hướng đối tượng dựa nhiều vào tính kế thừa để chia sẻ chức năng giữa các kiểu. Rust có cách tiếp cận khác: kết hợp. Thay vì kế thừa hành vi từ lớp cha, bạn tạo kiểu phức tạp bằng cách đưa các kiểu khác vào làm trường.

Hãy thử mô hình hóa một chiếc ô tô. Thay vì tạo lớp cơ sở Vehicle rồi kế thừa từ lớp đó, bạn kết hợp các thành phần nhỏ hơn, chuyên biệt để tạo nên Car:

struct Engine {
    horsepower: u32,
}

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

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

Car không kế thừa từ Engine hay Wheels. Nó có chúng. Quan hệ «có» này là composition. Bạn có thể truy cập các thành phần bên trong thông qua các trường của chúng và gọi trực tiếp các phương thức của chúng:

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

impl Car {
    fn start(&self) {
        self.engine.start();  // Giao cho thành phần bên trong xử lý
    }
}

Mẫu thiết kế này giúp mỗi struct tập trung vào một trách nhiệm duy nhất. Bạn cần thay đổi cách động cơ hoạt động? Chỉ cần chỉnh sửa struct Engine. Muốn dùng lại Wheels cho xe máy? Chỉ cần đưa nó vào một struct mới. Cách kết hợp này mang lại cho bạn sự linh hoạt mà không tạo ra sự phụ thuộc chặt chẽ như kế thừa thường gây ra.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống máy tính bằng cách kết hợp các thành phần! Thay vì tạo một struct khổng lồ, bạn sẽ kết hợp một Computer từ những thành phần nhỏ hơn, chuyên biệt: một CPU và một Memory. Mỗi thành phần sẽ biết cách tự mô tả, còn Computer sẽ giao việc cho các thành phần của nó.

Bạn sẽ sắp xếp code trong ba tệp:

  • cpu.rs: Định nghĩa một struct CPU công khai với hai trường công khai: cores (u32) để lưu số lõi và speed_ghz (f32) để lưu tốc độ xung nhịp. Thêm phương thức specs trả về một String mô tả CPU theo định dạng {cores}-core @ {speed_ghz}GHz.
  • memory.rs: Định nghĩa một struct Memory công khai với một trường công khai size_gb (u32) để lưu dung lượng bộ nhớ. Thêm phương thức specs trả về một String theo định dạng {size_gb}GB RAM.
  • main.rs: Đưa cả hai module vào và tạo một struct Computer công khai, có trường cpu thuộc kiểu CPU và trường memory thuộc kiểu Memory. Cài đặt phương thức system_info trên Computer để giao việc cho các thành phần và in ra thông số đầy đủ của hệ thống. Dùng các đầu vào đã cho để tạo Computer và hiển thị thông tin.

Phương thức system_info cần in ra:

System: {cpu_specs} | {memory_specs}

Ví dụ, với các đầu vào 8, 3.5 và 16:

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

Và với các đầu vào 4, 2.8 và 32:

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

Bạn sẽ nhận ba đầu vào: số lõi CPU (phân tích thành u32), tốc độ CPU (phân tích thành f32) và dung lượng bộ nhớ (phân tích thành u32).

Tự làm thử

mod cpu;
mod memory;

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

// TODO: Định nghĩa struct Computer công khai với hai trường công khai:
// - cpu: CPU
// - memory: Memory

// TODO: Triển khai phương thức system_info trên Computer để:
// - Gọi cpu.specs() và memory.specs()
// - In ra: 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: Tạo các instance CPU và Memory từ đầu vào đã phân tích
    
    // TODO: Tạo một instance Computer chứa CPU và Memory
    
    // TODO: Gọi system_info() trên computer để in ra kết quả
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Rust online