Join Kevin Skoglund for an in-depth discussion in this video Solution: Inheritance, part of PHP: Object-Oriented Programming.
(digitized jingle) - [Instructor] Hopefully you were able to complete the challenge assignment on inheritance. Remember there is no absolute right or wrong answer to this. The goal of the challenge was to get a feel for how inheritance works. As a demonstration of the kinds of results that you should have had, I'm going to show you the solution that I came up with using furniture as a category. Once I decided to use the furniture category, I tried to think of subclasses that had some properties in common and some differences.
There are common properties to all furniture. All furniture has a width, a depth, and a height and therefore we can also calculate the area of the amount of floor space that it takes up and the volume. So all of my subclasses are going to inherit those behaviors. I decided to choose two main subclasses, which are bed and sofa. A bed is a piece of furniture that you sleep on, so I decided there'd be an attribute called is_sleeper that would determine if we could sleep on it and a sofa is something that you sit on, so it's going to have property called is_seating.
Now of course you can sit on a bed and you can sleep on a sofa, but I'm talking about its intended purpose. Now a sofa can also be a sleeper sofa, so it's an attribute that we can change. By default it's not going to be a sleeper, but we change that attribute so that it becomes a sleeper sofa. Below sofa I decided to expand with some more subclasses and I chose couch, loveseat, and bench. The terms couch and sofa are often used interchangeably, but technically a couch is a sofa that doesn't have any arms.
You may not have known that. So it's going to inherit sofa and have all of it's behaviors, but by default, instead of having two arms, it's going to have zero. And if a couch has zero arms, then a bench is essentially the same thing as couch, but without a back on it. A loveseat is another kind of sofa, it's just narrower, which means that it has less seating. A sofa typically seats three people, a loveseat typically seats two. Once I had an idea of the hierarchy that I wanted to use and I had a sense of the attributes that would be shared between the different classes, then I set out to write the code for it.
The first thing that I did was I created a new file inside the sandbox called challenge_02.php and I set out to write my furniture class. So I gave it a width, a depth, and a height property and I gave it methods for area and volume. Then I also added properties for is_seating and is_sleeper which default to false. By default, furniture's going to have those set to false. And that's because other kinds of furniture I might want to add in the future might be a cabinet or a desk or something like that. So by default they're going to be false.
And I also added another one for is_upholstered which is also set to false. All right let's fold up furniture. We can just click right and fold it up. And then let's take a look at the bed class. Bed is going to be a subclass of furniture. It's going to inherit all of the properties and methods we just defined, but it's going to override is_sleeper to be is true. I decided to just leave a bed at that. A bed is just a piece of furniture you can sleep on and I didn't go any further. On sofa, I set is_seating equal to true by default and is_upholstered equal to true by default.
I overrode each one of those. I also added some new properties. I said that it has a seats property that defaults to three. Has seat cushions is equal to true, has back cushions is equal to true, and has arms is equal to two, all by default. Now of course, different kinds of sofas can be different. Some of them may have seat cushions, may have back cushions, and so on. These are attributes that we can change. Now I could have certainly put those up into the furniture class and inherited them, but I decided they were unique enough to this seating type of furniture that I would include it here.
I could have also had another subclass in between called seating furniture and put them there, but that was a bit of overkill for what I was trying to do here, so I just introduced them as an extension of the furniture class inside my sofa class. I also added another one for depth_opened. The idea is, if this turns out to be a sleeper sofa, then it's depth is different. It's width is the same but its depth changes. So I wanted to be able to define that in that case. Now you don't see is_sleeper here, but remember that's something we're inheriting. Is_sleeper is false by default, but if it were set to true, then we would want to take into account the depth_opened.
So I also created a new method here called area_opened. It's going to check and see if it's a sleeper or not. If it's not a sleeper, then we'll just return the regular area, but if it is a sleeper, then we want to calculate the area using depth_opened instead of the regular depth. Let's fold that up and then let's take a look at the last three, couch, loveseat, and bench. A couch is just a sofa that defaults to having zero arms. Now I could have one arm or two arms, but by default we're going to say it has zero. A loveseat is just a sofa that has two seats instead of three.
And a bench is just a couch that has no back cushions. What I want you to notice here, is that I'm creating a new class, a new type of object that I can work with, but it's inheriting a lot of behaviors from those parent classes. So even thought its definition is quite simple, there's lots and lots of complexity there. And if in the future, I come back and I add more methods or properties to furniture, well they're automatically going to appear in all of these different subclasses. That's one of the advantages to using inheritance in object-oriented programming.
I can show you an example of that. I've written a function here called inspect_class. This is not inside an object. This is a procedural function. There's no problem in mixing object-oriented programming and procedural programming. And it's just going to take a class and it's going to find out the parent class, its class bars, and its class methods and output those for us to read. Here, you can see I'm getting list of the class names and I'm looping through them and I'm calling that inspect_class function and I'm just calling nl2br to turn the new lines into br tags, so it'll be nicely formatted.
Before we go on, let's take a look at that. I'm going to save that file. Let's come over her to Firefox and let's load up challenge_02.php. And you can see what it gives you. Furniture, here's the different properties, here's the different methods. Bed extends furniture. Here's the properties, here's the methods, and so on. Notice when we get down here to bench, notice all the properties and the methods that it has. And it's overridden some things, has_seatcushions is one, has_backcushions is zero.
Right it doesn't show anything 'cause it's false so we don't see it there. But is_seating, is_upholstered, right, all those things are being inherited even though our class definition is really quite small. Okay, so now that we've seen the different ways inheritance works, let's try it out. I'm going to create a new sofa. I'm going to give it a width, a depth, and a height and then I can return its area and its volume. I'm also going to return it's area_opened. Now this is not a sleeper sofa. Right, I haven't told it, by default it's not a sleeper.
So area_opened should be the same as the area. And then I'm going to change it into a sleeper sofa. I'm going to say, you know what, let's make it a sleeper sofa and let's give it depth_opened and let's calculate that value again, see what we get back. Let's go over here and let's take a look at that and you'll see we get the area, eight, the volume is 24. Area_opened is eight when it's not a sleeper sofa. Once I convert it into a sleeper sofa, the area_opened changes into being 28. And then down here for our bench, create a new bench, right, a new instance of the bench class.
So it's going to inherit all the behaviors of the parent classes as well as as the extensions and overrides that we've done in the bench class. So I have width depth and height. I can get its area and then I can check, is it seating, is it sleeping, does it have back cushions. And you can see here, here's the area. Seating is true, sleeping is false, back cushions is false. So again, there is no absolute right answer to what you should have come up with here. But you should now have a feel for how inheritance works.
- 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