Polymorphism is an OOP feature that allows us to work with different classes that implement the same interface. It is one of the beauties of object-oriented programming. It allows the developer to create a complex system of classes and hierarchic trees, but offers a simple way of working with them.
Imagine that we have a function that, given a payer, checks whether it is exempt of taxes or not, and makes it pay some amount of money. This piece of code does not really mind if the payer is a customer, a librarian, or someone who has nothing to do with the bookstore. The only thing that it cares about is that the payer has the ability to pay. The function could be as follows:
function processPayment(Payer $payer, float $amount) { if ($payer->isExtentOfTaxes()) { echo "What a lucky one..."; } else { $amount *= 1.16; } $payer->pay($amount); }
You could send basic or premium customers to
this function, and the behavior will be different. But, as both
implement the Payer
interface, both
objects provided are valid types, and both are capable of
performing the actions needed.
The checkIfValid
function takes a customer and a list of books. We already saw that
sending any kind of customer makes the function work as expected.
But what happens if we send an object of the class Librarian
, which extends from Payer
? As Payer
does not
know about Customer
(it is rather the
other way around), the function will complain as the type hinting
is not accomplished.
One useful feature that comes with PHP is the ability to check whether an object
is an instance of a specific class or interface. The way to use it
is to specify the variable followed by the keyword instanceof
and the name of the class or interface.
It returns a Boolean, which is true
if
the object is from a class that extends or implements the specified
one, or false
otherwise. Let's see some
examples:
$basic = new Basic(1, "name", "surname", "email"); $premium = new Premium(2, "name", "surname", "email"); var_dump($basic instanceof Basic); // true var_dump($basic instanceof Premium); // false var_dump($premium instanceof Basic); // false var_dump($premium instanceof Premium); // true var_dump($basic instanceof Customer); // true var_dump($basic instanceof Person); // true var_dump($basic instanceof Payer); // true
Remember to add all the use
statements for each of the class or interface,
otherwise PHP will understand that the specified class name is
inside the namespace of the file.