freeCodeCamp/guide/english/php/class-inheritance/index.md

6.5 KiB
Raw Blame History

title
Class Inheritance

Class Inheritance

REUSE CODE WITH INHERITANCE IN OBJECT ORIENTED PROGRAMMING

Here, we will talk about how we can re-use code that we wrote without having any code duplication by using inheritance.

Man Class

This is our Man class:

<?php
class Man
{
    // 1. Declare the class variables
    public $name;
    protected $age;
    public $height;
    public $fav_sports;
    private $fav_drinks;
    
    // 2. Create a constructor method with 3 required parameters: name, age and height
    public function __construct($name, $age, $height)
    {
        // 2A. Assign the values of parameters to class properties
        // Also known as instance variables
        // Using "$this->property_name"
        $this->name = $name;
        $this->age = $age;
        $this->height = $height;
        
        // 2B. Print out the man's attributes and values upon instantiation
        echo "Our man's name is: " . $this->name . "\n";
        echo "He is " . $this->age . " years old and " . $this->height . " tall.";
    }
 
    // 3. Create class methods
    public function giveFirmHandshakes()
    {
        return "I give firm handshakes.";
    }
 
    public function beStubborn()
    {
        return "I am stubborn.";
    }
 
    public function notPutToiletPaper()
    {
        return "It's not humanly possible to remember to put toilet paper rolls when they are finished";
    }
    
    // 4. Age getter method
    public function getAge()
    {
        return $this->age;
    }
    
    // Age setter method
    public function setAge($age)
    {
        $this->age = $age;
    }
    
    // 5. Favorite Drinks setter method
    public function setFavDrinks($drinks = array())
    {
        if ($drinks) {
            $this->fav_drinks = $drinks;
        }
    }
    
    // Favorite Drinks getter method
    public function getFavDrinks()
    {
        return $this->fav_drinks;
    }
}

Healthy Man

Lets say we want to create another class called HealthyMan which has all the properties and methods of Man class.

Without having to re-write all the code for Man class, we can re-use that code by using the keyword extends.

<?php
class HealthyMan extends Man
{

}

Now we have all the class properties and methods from Man inside HealthyMan. We can instantiate HealthyMan class to check this real quick.

<?php
$jackie = new HealthyMan('Jackie', 25, '5\' 5"');
// => Our man's name is: Jackie
// => He is 25 years old and 5' 5" tall.

We can go ahead and set HealthyMan aka Jackies favorite sports and drinks.

<?php
$jackie->fav_sports = ['swimming', 'weight training'];
print_r($jackie->fav_sports);
// =>
// Array
// (
//     [0] => swimming
//     [1] => weight training
// )

$jackie->setFavDrinks(['Matcha tea', 'Oolong Tea']);
print_r($jackie->getFavDrinks());
// =>
// Array
// (
//     [0] => Matcha tea
//     [1] => Oolong Tea
// )

Now lets see if we can call Mans class methods like giveFirmHandshakes(), beStubborn() and notPutToiletPaper().

<?php
echo "\n" . $jackie->giveFirmHandshakes();
// => I give firm handshakes.

echo "\n" . $jackie->beStubborn();
// => I am stubborn.

echo "\n" . $jackie->notPutToiletPaper();
// => It's not humanly possible to remember to put toilet paper rolls when they are finished

We get all of these by just inheriting Man class using the keyword extends.

A Real Healthy Man

If we just inherit HealthyMan from Man class and do nothing with it, then it beats the whole purpose.

HealthyMan class has additional properties like body_fat_percentage and workout_per_week, and methods like eatHealthy(), meditateDaily() and laughOften().

Since these are personal properties, we can either set them visibility of protected or private and create setter/getter methods for the full encapsulation.

<?php
class HealthyMan extends Man
{
    /**
     * HealthyMan properties
     */
    private $body_fat_percentage;
    private $workout_per_week;
    
    /**
     * HealthyMan methods
     */
    public function eatHealthy()
    {
        return "I only eat healthy meals.";
    }
    
    public function meditateDaily()
    {
        return "I set aside 20 minutes daily to meditate.";
    }
    
    public function laughOften()
    {
        return "I watch funny TV shows to unwind myself.";
    }
    
    /**
     * HealthyMan Setters and Getters
     */
    public function setBodyFatPercentage($fat_percentage)
    {
        $this->body_fat_percentage  = $fat_percentage;
    }
    
    public function getBodyFatPercentage()
    {
        return $this->body_fat_percentage;
    }
    
    public function setWorkoutPerWeek($workout_times)
    {
        $this->workout_per_week = $workout_times;
    }
    
    public function getWorkoutPerWeek()
    {
        return $this->workout_per_week;
    }
}

We can call these methods to see if they are working as expected:

<?php

echo "\n" . $jackie->eatHealthy();
// => I only eat healthy meals.

echo "\n" . $jackie->meditateDaily();
// => I set aside 20 minutes daily to meditate.

echo "\n" . $jackie->laughOften();
// => I watch funny TV shows to unwind myself.

$jackie->setBodyFatPercentage(12);
echo "\nBody Fat %: " . $jackie->getBodyFatPercentage();
// => Body Fat %: 12

$jackie->setWorkoutPerWeek(5);
echo "\nWorkout Times Per Week: " . $jackie->getWorkoutPerWeek();
// => Workout Times Per Week: 5

We have successfully re-used the existing code and implemented a child class.

Is He That Stubborn?

Even though he inherited beStubborn() from Man class, since Jackie is a healthy man, he is only stubborn only once in a while. We can have Healthy Mans beStubborn() method to say “I am stubborn once in a while” instead of just plain old “I am stubborn” by overriding the parent class method.

<?php
class HealthyMan extends Man
{
    .....
    .....

    public function beStubborn()
    {
        return "I am stubborn once in a while.";
    }

    .....
    .....
}

Now when we can Jackies beStubborn() method, we will see a different output than before:

<?php
echo "\n" . $jackie->beStubborn();
// => I am stubborn once in a while.

This demonstrates how method overriding works in OOP.

By using method overriding, we are basically re-declaring the parent class method inside the child class.

This way, any instance of the parents class maintains its original method whereas any instance of the child class has the modified or overridden method.