LearnInheritance in object-oriented PHP

Inheritance in object-oriented PHP

One of the main advantages of object-oriented programming is the ability to reduce code duplication with inheritance. Code duplication occurs when a programmer writes the same code more than once, a problem that inheritance strives to solve. In inheritance, we have a parent class with its own methods and properties, and a child class (or classes) that can use the code from the parent. By using inheritance, we can create a reusable piece of code that we write only once in the parent class, and use again as much as we need in the child classes.

How can a class inherit the code of another class?

Inheritance allows us to write the code only once in the parent, and then use the code in both the parent and the child classes.

In order to declare that one class inherits the code from another class, we use the extends keyword. Let's see the general case:

class Parent {
  // The parent’s class code
}
 
class Child extends Parent {
  // The  child can use the parent's class code
}

The child class can make use of all the non-private methods and properties that it inherits from the parent class. This allows us to write the code only once in the parent, and then use it in both the parent and the child classes.

In the example given below, the SportsCar class inherits the Car class, so it has access to all of the Car’s methods and properties that are not private. This allows us to write the setModel() and hello() public methods only once in the parent, and then use these methods in both the parent and the child classes.

//The parent class
class Car {
  // Private property inside the class
  private $model;
 
  //Public setter method
  public function setModel($model)
  {
    $this -> model = $model;
  }
 
  public function hello()
  {
    return "beep! I am a <i>" . $this -> model . "</i><br />";
  }
}
 
 
//The child class inherits the code from the parent class
class SportsCar extends Car {
  //No code in the child class
}
 
 
//Create an instance from the child class
$sportsCar1 = new SportsCar();
  
// Set the value of the class’ property.
// For this aim, we use a method that we created in the parent
$sportsCar1 -> setModel('Mercedes Benz');
  
//Use another method that the child class inherited from the parent class
echo $sportsCar1 -> hello();

Result:
beep! I am a Mercedes Benz

How can a child class have its own methods and properties?

Just as a child class can use the properties and methods of its parent class, it can have properties and methods of its own as well. However, while a child class can use the code it inherited from the parent, the parent class is not allowed to use the child class’s code.

In the example given below, we will add to the child class some code of its own by adding the $style property as well as the driveItWithStyle() method:

// The parent class has its properties and methods
class Car {
  
  //A private property or method can be used only by the parent.
  private $model;
  
  // Public methods and properties can be used by both the parent and the child classes.
  public function setModel($model)
  {
    $this -> model = $model;
  }
   
  public function getModel()
  {
    return $this -> model;
  }
}
 
  
//The child class can use the code it inherited from the parent class, 
// and it can also have its own code 
class SportsCar extends Car{
 
  private $style = 'fast and furious';
 
  public function driveItWithStyle()
  {
    return 'Drive a '  . $this -> getModel() . ' <i>' . $this -> style . '</i>';
  }
}
 
 
//create an instance from the child class
$sportsCar1 = new SportsCar();
   
// Use a method that the child class inherited from the parent class
$sportsCar1 -> setModel('Ferrari');
  
// Use a method that was added to the child class
echo $sportsCar1 -> driveItWithStyle();

Result:
Drive a Ferrari fast and furious.

The protected access control modifier

When we declare a property or a method as protected, we can approach it from both the parent and the child classes.

In a previous tutorial, we learned that we can use the public access modifier to allow access to a class’s methods and properties from both inside and outside the class. We also learned that those methods and properties that are private can only be used from inside the class.

In this tutorial, we will learn about a third modifier - the protected modifier, which allows code usage from both inside the class and from its child classes.

The first example demonstrates what might happen when we declare the $model property in the parent as private, but still try to access it from its child class.

What do you think might happen when we try to call a private method or property from outside the class?

Here is the code:

// The parent class
class Car {
  //The $model property is private, thus it can be accessed 
  // only from inside the class
  private $model;
  
  //Public setter method
  public function setModel($model)
  {
    $this -> model = $model;
  }
}
  
   
// The child class
class SportsCar extends Car{
  //Tries to get a private property that belongs to the parent
  public function hello()
  {
    return "beep! I am a <i>" . $this -> model . "</i><br />";
  }
}
   
//Create an instance from the child class
$sportsCar1 = new SportsCar();
  
//Set the class model name
$sportsCar1 -> setModel('Mercedes Benz');
   
//Get the class model name
echo $sportsCar1 -> hello();

Result:
Notice: Undefined property: SportsCar::$model

We get an error because the hello() method in the child class is trying to approach a private property, $model, that belongs to the parent class.

We can fix the problem by declaring the $model property in the parent as protected, instead of private, because when we declare a property or a method as protected, we can approach it from both the parent and the child classes.

// The parent class
class Car {
  //The $model property is now protected, so it can be accessed 
  // from within the class and its child classes
  protected $model;
   
  //Public setter method
  public function setModel($model)
  {
    $this -> model = $model;
  }
}
  
// The child class
class SportsCar extends Car {
  //Has no problem to get a protected property that belongs to the parent
  public function hello()
  {
    return "beep! I am a <i>" . $this -> model . "</i><br />";
  }
}
  
//Create an instance from the child class
$sportsCar1 = new SportsCar();
  
//Set the class model name
$sportsCar1 -> setModel('Mercedes Benz');
  
//Get the class model name
echo $sportsCar1 -> hello();

Result:
beep! I am a Mercedes Benz

Now it works, because we can access a protected code that belongs to a parent from a child class.

How to override the parent’s properties and methods in the child class?

In the same way that the child class can have its own properties and methods, it can override the properties and methods of the parent class. When we override the class’s properties and methods, we rewrite a method or property that exists in the parent again in the child, but assign to it a different value or code.

In the example given below, we create a hello() method in the parent class that returns the string "beep" and override it in the child class with a method by the same name that returns a different string, "Halllo".

Here is the code:

// The parent class has hello method that returns "beep".
class Car {
  public function hello()
  {
    return "beep";
  }
}
 
//The child class has hello method that returns "Halllo"
class SportsCar extends Car {
  public function hello()
  {
    return "Hallo";
  }
}
    
//Create a new object
$sportsCar1 = new SportsCar();
  
//Get the result of the hello method
echo $sportsCar1 -> hello();

Result:
Halllo

The result reflects the fact that the hello() method from the parent class was overridden by the child method with the same name.

How to prevent the child class from overriding the parent’s methods?

In order to prevent the method in the child class from overriding the parent’s methods, we can prefix the method in the parent with the final keyword.

In the example given below, we declare the hello() method in the parent as final, but still try to override it in the child class. What do you think might happen if we try to override a method that was declared as final?

// The parent class has hello method that returns "beep".
 
class Car {
  final public function hello()
  {
    return "beep";
  }
}
 
//The child class has hello method that tries to override the hello method in the parent
class SportsCar extends Car {
  public function hello()
  {
    return "Hallo";
  }
}
  
 
//Create a new object
$sportsCar1 = new SportsCar();
  
//Get the result of the hello method
echo $sportsCar1 -> hello();

Result:
Fatal error: Cannot override final method Car::hello()

Since we declared the hello method as final in the parent, we cannot override the method in the child class.

Conclusion

We use inheritance in order to reduce code duplication by using code from the parent class in the child classes.

In this tutorial we have learned one of the principles of object oriented programming, the concept of inheritance. We use inheritance in order to reduce code duplication by using code from the parent class in the child classes.

In the next tutorial, we will learn about abstract classes and methods, which are classes that cannot be instantiated and methods that have no bodies.

But before we move on to the next lesson, lets practice: Practice inheritance in PHP

comments powered by Disqus