TL ; DR:
In many languages a child class inherits from a parent class and gets its fields and methods for free. Rust has no inheritance: a struct reuses another type by composition, holding it as a field and forwarding calls to it. This lets you reuse code instead of copy-pasting it.
struct Puppy {
dog: Dog,
}
impl Puppy {
fn new(name: &str) -> Puppy {
Puppy { dog: Dog { name: name.to_string() } }
}
fn whine(&self) { println!("whimper"); }
}
Full lesson:
Inheritance is one of the four classic OOP pillars (along with encapsulation, polymorphism, and abstraction). The idea is simple: most real-world things are kinds of other things — a Puppy is a Dog, a Car is a Vehicle, a Manager is an Employee. In languages with classes, the child class gets the parent's data and behavior automatically. Rust has no class inheritance; instead a Puppy has a Dog inside it, and you reuse the Dog's data and behavior through that field.
What gets reused?
- Fields — the Puppy holds a
Dogin itsdogfield, so thenameis reachable asself.dog.nameeven though we only declared it on Dog. - Methods — the Puppy gets a
bark()method that forwards toself.dog.bark(); methods are not promoted automatically. - The contract — Rust doesn't let you pass a Puppy where a Dog is expected; shared behavior is expressed with traits instead (we'll see this when we cover polymorphism).
What you still write
- The constructor
Puppy::newhas to build the innerDogitself (because the Dog's fields need initializing). - Any new methods or new fields specific to the puppy.
Your task
Below the Dog struct, create a Puppy struct that wraps a Dog, with a new function, a bark() that forwards to the dog, and one new method, whine(), that prints "whimper". The code in main_function creates a Puppy named "Buddy", calls its forwarding bark(), and then its new whine().
Expected output:
Woof! I am Buddy
whimperFree plan: 30 tutor messages. PRO is unlimited.
