Introduction
If the Dog class is a child class of the Animal class (if Dog extends Animal) - Dog is a subclass or subtype of Animal, and parent class Animal is the superclass or supertype of Dog.
This is the basic mechanism of inheritance.
Consider the following code:
We declare the Animal class and Dog, a subclass of Animal.
We create the printMovement() function, which takes any object of the type Animal and calls that object's move() method.
The printMovement() uses a type hint to specify that it expects to receive an Animal object, but when we call that function and pass along a Dog object, everything works fine.
You may have expected an error to be thrown, but that is not the case.
All Dog objects are also Animal objects, so they inherit all of Animal's properties and methods, including the move() method.
And because printMovement() knows it will always receive an object of a class that contains the move() method, PHP knows it can safely execute the move() method on the received object without risking an error like "Call to undefined method move()".
Remember type hints
Type hints make your code more robust by telling the PHP interpreter which exact object types your functions and methods expect.
It also reduces the amount of code you need to write because you no longer need to check if the objects you receive are of the expected type, contain a certain method, and so on.
When you specify which object type / class a function or method expects, PHP will only allow that function or method to accept parameters of the specified type or any of its subtypes.
In other words, with type hints your functions know exactly what types of objects they will receive.
Example
Consider the following class hierarchies and function:
- Animal
- Horse
- Dog
- Poodle
- GermanShepherd
- Vehicle
- Car
- Bicycle
function adopt(Animal $animal) {
// Do something.
}The adopt() function will accept variables of the type Animal, Dog, and Poodle. It will NOT accept variables of the type Vehicle nor any of Vehicle's subtypes, because those are not Animals or subtypes of Animal.
Animals, Dogs, and Poodles are guaranteed to have the same common properties and methods, so a function that accepts an Animal object can also work with Dog or Poodle objects.
But this is not the case the other way around!
A function that expects a Poodle can NOT accept a Dog or Animal object because those types are not guaranteed to contain the Poodle properties and methods the function relies on, expecting only Poodle objects.
Remember:
Poodles are Dogs and Dogs are Animals, so if you expect to be given an Animal and receive a Poodle or Dog, you're happy. You got what you expected.
Animals and Dogs are not necessarily all Poodles, so if you expect to be given a Poodle, but receive a GermanShepherd or a Horse instead, you're not happy and might not even know what to do with it.
Real-world analogy
Dog trainers train any kind of dog as long as it's a dog: poodles, labradors and chihuahuas are all accepted. But they don't train horses because horses are not dogs and dog trainers are not trained to work with horses.
Summary
- When you specify which object type (class) a function or method expects, PHP will only allow that function or method to accept parameters of the specified type or any of its subtypes.
- The ability for a method to expect parameters of specific types but also allow subtypes of the specified types, is a form of polymorphism: the method accepts different forms or variations of the specified type.