Method Overriding Revisited
Part of the Object Oriented Programming section of Coddy's PHP journey — lesson 33 of 91.
You've already learned about method overriding in the Inheritance chapter. Now let's explore how it connects to polymorphism - one of the most powerful concepts in object-oriented programming.
Polymorphism means "many forms." When you override a method in a child class, you're giving that method a different form while keeping the same name. The magic happens when you work with objects through their parent type:
<?php
class Animal {
public function speak() {
return "Some sound";
}
}
class Dog extends Animal {
public function speak() {
return "Woof!";
}
}
class Cat extends Animal {
public function speak() {
return "Meow!";
}
}
function makeAnimalSpeak(Animal $animal) {
return $animal->speak();
}
echo makeAnimalSpeak(new Dog()) . "\n";
echo makeAnimalSpeak(new Cat());
Output:
Woof!
Meow!The function makeAnimalSpeak() accepts any Animal. It doesn't know or care whether it receives a Dog or Cat. PHP automatically calls the correct overridden method based on the actual object type at runtime.
This is polymorphism in action.
This approach lets you write flexible code that works with a family of related objects without knowing their specific types. You can add new animal classes later, and the function will work with them automatically.
Key Point: Method overriding enables polymorphism by allowing different classes to respond differently to the same method call, determined at runtime by the actual object type.
Challenge
EasyLet's build a musical instrument system that demonstrates polymorphism through method overriding. You'll create a base Instrument class and two child classes that each produce their own unique sound — then use a single function to play any instrument polymorphically.
You'll organize your code across four files:
Instrument.php— Create anInstrumentclass with a protected$nameproperty set through the constructor. Add aplay()method that returns"[name] makes a sound". This serves as the base behavior that child classes will override.Guitar.php— Create aGuitarclass that extendsInstrument. Include the parent file. The constructor accepts the name and passes it to the parent constructor. Override theplay()method to return"[name] strums a chord".Drum.php— Create aDrumclass that extendsInstrument. Include the parent file. The constructor accepts the name and passes it to the parent constructor. Override theplay()method to return"[name] beats a rhythm".main.php— Include both the Guitar and Drum files. Create a function calledperformWiththat accepts anInstrumentparameter (type-hinted) and returns the result of callingplay()on it. This function demonstrates polymorphism — it works with any instrument type through the parent class type hint.
You'll receive two inputs: a name for the guitar and a name for the drum. Create a Guitar and a Drum with these names. Pass each one to your performWith() function and print the results — the guitar first, then the drum, each on its own line.
Notice how performWith() accepts any Instrument, yet PHP automatically calls the correct overridden play() method based on the actual object type at runtime. That's polymorphism in action!
Cheat sheet
Polymorphism means "many forms" and allows objects of different classes to be treated through their parent type while maintaining their specific behavior.
When you override a method in child classes, PHP automatically calls the correct version based on the actual object type at runtime:
<?php
class Animal {
public function speak() {
return "Some sound";
}
}
class Dog extends Animal {
public function speak() {
return "Woof!";
}
}
class Cat extends Animal {
public function speak() {
return "Meow!";
}
}
function makeAnimalSpeak(Animal $animal) {
return $animal->speak();
}
echo makeAnimalSpeak(new Dog()); // Woof!
echo makeAnimalSpeak(new Cat()); // Meow!
The function makeAnimalSpeak() accepts any Animal type through its parameter type hint. It doesn't need to know the specific class - PHP determines which overridden method to call at runtime based on the actual object type.
This enables flexible code that works with a family of related objects without knowing their specific types. New child classes can be added later and will work automatically with existing functions.
Try it yourself
<?php
// Include the instrument files
require_once 'Guitar.php';
require_once 'Drum.php';
// Read input
$guitarName = trim(fgets(STDIN));
$drumName = trim(fgets(STDIN));
// TODO: Create a function called performWith that:
// - Accepts an Instrument parameter (use type hint: Instrument $instrument)
// - Returns the result of calling play() on the instrument
// TODO: Create a Guitar with $guitarName and a Drum with $drumName
// TODO: Pass each to performWith() and print the results (guitar first, then drum)
?>This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe $this KeywordMethodsPropertiesConstructor (__construct)Destructor (__destruct)Recap - Simple Calculator4Inheritance
Basic InheritanceThe parent:: KeywordMethod OverridingThe final KeywordAbstract ClassesRecap - Employee Hierarchy7Encapsulation
Public, Protected, PrivateAccess Modifiers in DepthGetters and SettersInformation HidingConstructor Promotion (8.0)Recap - Student Records System2Namespaces & Autoloading
Introduction to NamespacesThe use KeywordPSR-4 Autoloading StandardComposer AutoloaderRecap - Organized Project5Interfaces & Contracts
Introduction to InterfacesImplementing InterfacesMultiple Interface ImplementInterface vs Abstract ClassType Hinting with InterfacesRecap - Shape Calculator8Magic Methods
Magic Methods Introduction__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Object Cloning__serialize & __unserializeRecap - Custom Collection11Type System & Error Handling
Type DeclarationsNullable TypesUnion & Intersection TypesException ClassesCustom Exception HierarchyTry, Catch, FinallyRecap - Form Validator14Project: Library Management
Project OverviewBook and User Classes3Class Properties
Instance vs Static PropertiesConstants in ClassesStatic Methods & PropertiesPrivate & Protected PropertiesReadonly Properties (PHP 8.1)Recap - Bank Account Manager6Polymorphism
Method Overriding RevisitedPolymorphism via InterfacesType Hinting & Union TypesLate Static BindingRecap - Payment Processor9Traits
Introduction to TraitsUsing Multiple TraitsTrait Conflict ResolutionAbstract Methods in TraitsTraits vs Inheritance12Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy Pattern