TL ; DR:
When a struct that embeds a parent defines a method with the same name as the parent's, the child's version overrides (shadows) the parent's. Different objects can give the same method name different behavior.
type Dog struct{}
func (d Dog) bark() { fmt.Println("Woof!") }
type Puppy struct{ Dog }
func (p Puppy) bark() { fmt.Println("Yip!") }
Full lesson:
You've seen that a struct that embeds another gets the embedded struct's methods. Overriding is what happens when the child wants to change one of those inherited methods.
Why override?
A Puppy is a special kind of Dog, but it sounds different — "Yip!" instead of "Woof!". Instead of inventing a new method name, you redefine bark() on the Puppy. Calling bark() on a Puppy value runs the Puppy's version.
How it works in each language
- Go — there are no
virtualoroverridekeywords. A method declared onPuppywith the same name as one promoted from the embeddedDogsimply shadows it. The shadowing is by the static type: code insideDog's own methods still callsDog'sbark. The original stays reachable asbuddy.Dog.bark(). - C# — the parent method must be marked
virtual, the child marks its replacementoverride. The compiler enforces this pairing. - Java — every non-final method is virtual by default; the
@Overrideannotation is optional but tells the compiler to verify the signature matches. - Python — defining a method with the same name in the child class replaces the parent's. No keyword required.
- JavaScript — same as Python: define the method again on the child class and it wins.
- C++ — the parent method must be
virtual;overrideon the child is optional but compiler-checked.
Your task
The Dog struct already has a bark method. Give Puppy its own bark method so it prints "Yip! I am " followed by the puppy's name. The harness creates a Puppy named "Buddy" and calls bark() on it.
Expected output:
Yip! I am BuddyFree plan: 30 tutor messages. PRO is unlimited.
