Learn PHP in One Day and Learn It Well

PHP for Beginners with Hands-on Project. The only book you need to start coding in PHP immediately. By Jamie Chan

Chapter 10: Inheritance

In the previous chapter, we covered the fundamentals of OOP. Some of the concepts in OOP can be confusing for beginners. If this is the first time you are exposed to OOP, you may want to read through the previous chapter more than once to fully grasp the concepts.

Once you are comfortable with the topics covered in Chapter 9, we are ready to proceed to a more advanced, but equally important, concept in OOP – inheritance.

As the name suggests, inheritance has to do with the relationship between two or more classes. With inheritance, classes can be declared such that one class is a child class (also known as a subclass) of another (known as the parent class or base class). This enables us to group related classes together.

The easiest way to explain inheritance is to look at an example.

10.1 Writing the Child Classes

We’ll use the Movie class in Chapter 9 as a parent class to illustrate. Open Brackets and create a new file called AwardWinningMovie.php. Save this file to your htdocs folder.

Add the following code to AwardWinningMovie.php:

<?php 
include "Movie.php";
class AwardWinningMovie extends Movie{
	private $award;
 	  public function __construct($pId, $pTitle, $pRentalPrice, $pAward){
 		parent::__construct($pId, $pTitle, $pRentalPrice); 	  $this->award = $pAward;
    }
 }

In the code above, we first use the include statement to include the code for the Movie class. Next, we create a class called AwardWinningMovie .

Notice a new keyword extends in the AwardWinningMovie class declaration? This keyword indicates that AwardWinningMovie is a child class of Movie .

When one class is a child class of another, it inherits all the public and protected members of the parent class. In other words, it can access and use those members directly, as if they are part of its own code. We’ll illustrate what this means later.

Within the AwardWinningMovie class, we declare a private property called $award . Next, we declare a constructor with 4 parameters, $pId$pTitle$pRentalPrice and $pAward .

Within the constructor, notice a new keyword, parent ?

As you may have guessed, this keyword is used to call the parent class constructor. As the child class has its own constructor, we need to use the parent keyword and the :: operator when we want to access the parent class constructor. When we call the parent class constructor, we do not create a new object. Instead, we use the name of the constructor ( __construct() ).

In our example, we pass the values of $pId$pTitle and $pRentalPrice as arguments to the parent class constructor. These values will be used to initialize the $id$title and $rentalPrice properties declared in the parent class respectively.

As these properties were declared as private in the parent class, we are not allowed to access them directly in the child class. Instead, we can only initialize them using the parent class constructor, which is a public method.

Next, we have the statement

$this->award = $pAward;

This statement is used to initialize the $award property declared in the child class.

With that, the child class constructor is complete.

Now, let’s add another method to the child class. Add the code below to the AwardWinningMovie class, after the __construct() method but before the closing brace of the class:

public function recommend($country){
	switch ($this->award){
	  case 'Best Picture':
 	    $others = 'The Rail';
 	    break;
 	  case 'Best Actor':
 		$others = '1729';
 		break;
 	  default:
 $others = 'And so it begins';
 }
 return
 	'You might also like:<BR>'.
 	'<BR>Movie Title = '.$others.
 	'<BR>Rental Price = '.$this->conversion($country);}

Here, we declare a method called recommend() that has one parameter – $country . Within the method, we use a switch statement to assign different values to the local variable $others , depending on the value of $this->award .

Next, we return a string recommending a new movie to users. This string should be quite self-explanatory, except for the last part where we use the $this keyword to call the conversion() method (refer to the underlined code above) .

Recall that we do not have a conversion() method in the AwardWinningMovie class? Will we get an error when we try to call this method?

The answer is no. This is because the AwardWinningMovie class is a subclass of the Movie class. Hence, it can access all the public and protected members of the parent class directly, as if they are part of its own code.

As the parent class – Movie – has a public method called conversion() , the child class can access this method simply by using the $this keyword. Got it?

This is one of the main reasons for using inheritance; it allows us to reuse existing code. In our example, the AwardWinningMovie class can use the conversion() method directly without having to code it itself.

10.2 Creating a Child Class Object

We are now ready to create a child class object. To do that, create a new file in Brackets and save it as chap10.php to the htdocs folder.

Add the following code to it:

<?php
	include 'AwardWinningMovie.php';
	  $awm = new AwardWinningMovie('A12324', 'Max', 6.99, 'Best Picture');
		echo $awm->recommend('Japan');

Here, we first use the include statement to include the AwardWinningMovie class.

Next, we use the new keyword to create an AwardWinningMovie object, passing 'A12324''Max'6.99 and 'Best Picture' as arguments to the constructor.

Finally, after creating the $awm object, we use it to call the recommend() method. If you run the code above, you’ll get

You might also like:
Movie Title = The Rail
Rental Price = 768.9

as the output. Straightforward?

10.3 Access Modifiers Revisited

Good! Let’s revisit the concept of access modifiers now.

Previously, we mentioned that when one class extends another, it inherits all the public and protected class members of the class it extends. What this means is that it can access those members directly without any restrictions. However, the same does not apply to private class members. Child classes are not allowed to access private members of the parent class directly.

To understand what this means, try changing the conversion() method in the Movie class to a private method. In other words, change the line

public function conversion($country)

in Movie.php to

private function conversion($country)

Next, load chap10.php again. What do you get? You get an error message similar to the output below, right?

Fatal error: Uncaught Error: Call to private method Movie::conversion() from context 'AwardWinningMovie'...

This is because when conversion() is a private method, we are not allowed to access it directly outside the class in which it is defined (i.e., outside the Movie class). Hence, the recommend() method in the AwardWinningMovie class is not allowed to access it.

Next, change conversion() to a protected method and load chap10.php again. Everything works now, right? This is because child classes are allowed to access protected members in their parent class directly. Hence, the recommend() method in the AwardWinningMovie class is now allowed to access the conversion() method in the Movie class. Got it? Great!

After changing conversion() to a protected method, note that we are only allowed to access it directly inside the class in which it is declared and any subclass that inherits from that class. In other words, we can only access it directly inside the Movie and AwardWinningMovie classes.

Recall that previously, we accessed the method in chap9.php? This was all right when conversion() was a public method. Now that it is a protected method, you’ll get an error if you load chap9.php again. If you want to access the conversion() method in chap9.php directly, you have to change it back to a public method.

10.4 Overriding

Now that you are familiar with child classes and inheritance, let’s move on to discuss the concept of overriding. Overriding occurs when a child class modifies the methods it inherits from its parent class.

To illustrate what this means, add the following line to chap10.php and load the page.

echo $awm->displayHeading('H1');

You’ll get the text “Award Winning Movies” displayed as a <H1> heading.

Here, we are calling the displayHeading() method declared in the parent class. This method is a public method inherited by the child class. Hence, we can access it using an AwardWinningMovie object.

Next, let’s see what happens if we code a new version of the displayHeading() method inside the child class itself. To do that, add the following method to the AwardWinningMovie class, after the recommend() method but before the closing brace of the class:

public function displayHeading($tag){
	$baseMsg = parent::displayHeading($tag);
	return $baseMsg.$this->award;
}

Here, we declare a method with the same name ( displayHeading ) and parameter list ( $tag ) as the method in the parent class. When that happens, we say that the child class method overrides the parent class method.

Within the child class method, we use the parent keyword to call the parent class displayHeading() method. Whenever a child class overrides a parent class method, we need to use the parent keyword (instead of the $this keyword) if we want to access the parent class method inside the child class.

Next, we assign the result returned by the parent class method to a variable called $baseMsg . Finally, we concatenate $baseMsg with the $award property in the child class and return the result.

If you load chap10.php again, you’ll see the text “Award Winning Movies” displayed as a <H1> heading, followed by a line that says “Best Picture”. This additional line illustrates that we are now accessing the displayHeading() method in the child class.

As displayHeading() has been overridden in the child class, the child class method is called when we access it using a child class object ( $awm ).

If we want to access the displayHeading() method in the parent class, we have to use a parent class object. For instance, we can do it as follows:

$mv = new Movie('A3244', 'Golden Rose', 3.99);
echo $mv->displayHeading('H1');

If you add the code above to chap10.php and load the page, you’ll only get “Award Winning Movies” (without “Best Picture”) added to the output. This illustrates that $mv is accessing the displayHeading() method in the parent class.