Start learning free

LESSON 405 OF 414 · OBJECT-ORIENTED PROGRAMMING

Extending the Parent Behavior in Rust (traits) in Rust

Practice

TL ; DR:

Rust has no class inheritance and no super. Shared behavior is described by a trait: Dog and Puppy are separate structs that both implement the trait Animal. A Puppy that wants to "extend" the dog's bark simply does what Dog's bark does first (the same println!) and then adds its own line.


impl Animal for Puppy {
    fn bark(&self) {
        println!("Woof! I am {}", self.name);   // what Dog's bark prints
        println!("Yip! Said {}", self.name);
    }
    fn name(&self) -> &str {
        &self.name
    }
}

Why it matters

Overriding a method replaces the parent's behavior. Often you want to extend it instead: keep what the parent did and add something more. A typical example is a save method: the parent writes the row to the database, and a subclass runs the parent's save first and then writes a log line.

Your task

There are no classes to extend here, so you write the whole program above the driver, in order:

  1. trait Animal with two methods: fn bark(&self); and fn name(&self) -> &str;;
  2. struct Dog { name: String } and impl Animal for Dog: bark prints Woof! I am <name> with println!("Woof! I am {}", self.name);, and name returns &self.name;
  3. struct Puppy { name: String } and impl Animal for Puppy: its bark first prints the same Woof! I am <name> line, then Yip! Said <name>; name returns &self.name;
  4. fn mainFunction() and the first line of the driver, let buddy = Puppy {, which the driver then completes.

Notes:

  • impl Animal for Puppy gives Puppy the methods the trait asks for. Every method of the trait must be written.
  • {} inside println! is replaced by the next argument, here self.name.

The driver (already written, it runs when you press Run):

let buddy = Puppy {
    name: "Buddy".to_string(),
};
buddy.bark();
let rex = Puppy { name: "Rex".to_string() };
rex.bark();
let dog = Dog { name: "Max".to_string() };
dog.bark();
  • buddy is a Puppy: its bark prints the parent's line, then its own.
  • rex is another Puppy: the names come from the object, nothing is hard-coded.
  • dog is a plain Dog: its bark is unchanged and prints only the parent's line, with no Yip!.

Expected output:

Woof! I am Buddy
Yip! Said Buddy
Woof! I am Rex
Yip! Said Rex
Woof! I am Max
STEP 1 OF 18
    Ctrl + Enter to check

    Base Keyword in Rust

    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free