Join Kevin Skoglund for an in-depth discussion in this video Refer to the parent class, part of PHP: Object-Oriented Programming.
- In this movie I want us to look at how subclasses are able to refer to behaviors which are in their parent class. So far when working with our static properties and methods we've seen a couple different ways that we can refer to them. The first is that we can use the class name followed by the scope resolution operator, and then either the property or the method name. We also saw that if we're working inside the class definition, we have another option, which is the keyword self. So we can swap out the class name for this keyword self.
But when we want to refer to the parent class we also have two options. The first is that we can use the actual class name, just like we did in that first example, or we have a keyword that we can swap in, and this is considered a best practice and a better way to do it, just like self is. If we're inside the definition of the class it's better to refer to the parent class as parent, and not a refer to whatever class is listed right after the keyword extends. That's the class that we're talking about.
So it's going to ask the parent for its property or method. Now this is only going to be for static properties and methods, not for instances. Now actually the same rules apply as with self, whereas it does work for methods, but you'll get a depracation warning saying, "Please don't do this because this feature "may go away in the future." So it's a best practice not to do it even though technically you can. And it makes sense that we wouldn't do that because self and parent are replacements for the class name.
So you would use parent followed by either the property or the method name. But the thing is, it's not actually needed for the static properties. You remember we talked about that those static properties are already shared with all the subclasses, it's a common variable that they're both using. So we don't need to use parent followed by a property name, because self followed by the property name refers to the same variable. Where it's useful is for calling static methods, especially after we've overwritten them in the subclass.
Let's look at the two most common cases where you might do this, because they're going to be very instructive. The first example shows how you extend the functionality of the parent static method. Here I have a class called chef and it has a public static function called make dinner in it. And it's just going to echo back the phrase, "cook food". Now I have a subclass called amateur chef and it's going to override make dinner. So the amateur chef's going to make dinner in a different way than the chef did. But notice that it still calls parent make dinner inside of it.
Essentially what I'm doing is I'm saying, "Hey, I want to do the same thing as my parent did, "but I have some business that I want to take care of, "either right before it, right after it, or both." We still want that parent's method, we don't want to have to rewrite it. We just want to wrap additional code around it, and this does that. So then if I call chef make dinner, it responds with, "cook food". But if I ask the amateur chef to make dinner, you'll see that I get back, "read recipe, cook food, clean up mess". This isn't a particularly real world example, but I hope that it does make clear this idea that you're able to do actions before and after what the parent method would do.
And where this really pays benefits, is if we decided to add another step to chef make dinner, the amateur chef would get that change too. The second common usage is to override the parent method but then to fall back to the parent if something goes wrong, or a condition is not met. So here for example, I have a class called image, it has a public static property for resizing enabled, which is currently set to true by default, and I have a public static method for geometry which returns just the string 800 by 600.
Now I have a subclass called profile image which is going to override geometry, and it's going to attempt to provide its own answer. Its own answer would be 100 by 100 but notice that it only returns that answer if resizing is enabled. If not, it's going to fall back to what the parent had. So it basically says, "Try to do this yourself, "but if for some reason you can't do it, "something goes wrong, or a condition is not met, "let's fall back to whatever our parent said "and see if the parent can handle it instead." Take a moment and also notice that when I'm referring to resizing enabled, I'm not calling parent resizing enabled, even though that's defined up in the parent class.
I don't have to because that's a shared property, so it's already inherited into the profile image class. So when we try it out we have our image geometry, of course we get back 800 by 600. If we ask for the profile image geometry we would get 100 by 100 as a default, because resizing is enabled. But if we then turn resizing off, notice here that I'm doing that in the parent class. It doesn't matter, it would work the same way if we did it with profile image. Then when I call profile image geometry, it's going to try and handle it itself by calling its own overwritten geometry method, but since resizing isn't enabled it's going to fall back to the parent.
So there are many reasons that you might call the parent but these are the two most common usages. Either to extend a current method with something either before it, or after it, or both; or to fall back to it if something goes wrong, or a condition is not met. Let's try these examples in our sandbox just so we can see them. I've already included a modified version of the code that we just looked at inside the file parent.php, which is in the exercise files. So you can see I have my chef class, I have my make dinner method, I've also added just a BR tag at the end here, just so we'll get a new line.
And then I have the amateur chef extending the chef, overriding make dinner, it's going to add additional steps here, it's then going to call the parent method, and then add additional steps afterwards. And then we'll actually call those things right here. Let's just take a look at that before we get to the second example. Let's save this, let's come back over here, and the name of this is just going to be parent.php. So chef is going to cook food. The amateur chef is going to read recipe, cook food, clean up mess.
See how that works? Okay let's come down here and let's look at the second example. Example of using a parent static method as a fallback, we have the resizing enabled set to true. I have the geometry by default just returning this string. Profile image is a subclass of image and it's going to try and handle the geometry method itself. It's going to check to see if resizing is enabled, if it is, it'll handle it itself. It'll return its own version but if not, then it's going to ask the parent to handle it for it.
So we can try both of those down here. You see we're asking for the parent geometry, the profile image geometry, then we change resizing enabled and try the profile geometry again. Let's just go back over here and let's reload it. And you can see we get 800 by 600 and 100 by 100, then we disable the resizing and we try it again, and this time the parent is handling it instead of the child. The idea of calling the parent class, and especially these two design patterns, the idea of either extending a method or falling back to a method, are important to have in your PHP toolbox.
- Defining classes
- Calling methods
- Class inheritance
- Extending and overriding classes
- Accessing and controlling access to properties and methods
- Static properties and methods
- Magic methods: constructor, destructor, and clone
- Creating a PHP OOP project