Wednesday 27 March 2019

Inheritance in PHP


When a programmer writes same code more than once, code duplication problem occurs. Inheritance provides the ability to reduce code duplication in programming.
In inheritance, there is a parent class having its own methods and properties and child class/classes use the code from the parent.
Inheritance make us capable of reuse a piece of code (written only once in parent class) again & again in child class as we need.

Inherit code of another class by a class.

Inheritance provides the capability of reuse the code (written only once in parent class) in both the parent and child classs.
"extends": This keyword declares that one class inherits code from another class. Example:

class Parent {
  // The parent’s class code
}

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

Child class inherits the parent class so child class can use all the non-private methods and properties of parent class. We write code only once in parent and can use this code in both the parent and child classes.
ExampleI am having a parent class "car" and child class "sportsCar". Child class "sportsCar" is inheriting parent class "car" so class sportsCar having access to all of the car's class non-private methods and properties.
We have written setModel() and hello() public methods only once in the parent class. Class sportsCar and car can both use these methods.


//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 "Hey! 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('Ferrari');
 
//Use another method that the child class inherited from the parent class
echo $sportsCar1 -> hello();


Result: Hey! I am a Ferrari


Can a child class have its own methods and properties?


In inheritance, Child class can use all non-private methods and properties of parent class. But child class can have its own methods and properties as well. Child class can use the code inherited from parent class but parent class cannot use the child's class code.
Example: I am adding a property $style and a method driveItWithStyle() in child class as below: 

// 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 a method or a property declared as protected, Both the parent and child class can use this method or property.
  • Private methods or properties can only be used from inside the class.
  • Public methods or properties can be accessed from both the inside and outside of the class.
  • Protected modifier: which allows code usage from both inside the class and from its child classes.
Example 1: What happen when we declare $model property as private in parent and still try to access it from its child class.

Try to call a private method or property from the outside of the class as done in code below:
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 "Hey! 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('Ferrari');
   
//Get the class model name
echo $sportsCar1 -> hello();
Result:  Notice: Undefined property: SportsCar::$model

In above example, we get an error because hello() method (in child class) trying to use $model private property of parent class.

Now to fix above error, we can declare $model property as protected instead of private. Because when we declare a method or property as protected, this method or property can be used in both the parent and 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 "Hey! 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('Ferrari');
  
//Get the class model name
echo $sportsCar1 -> hello();

Result: Hey! I am a Ferrari.

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

Override parent’s methods and properties in the child class?

Child class can have its own methods and properties. Child class can also override the methods and properties of the parent class as well.
To override class methods and properties, rewrite that method or property in child class which already exists in the parent class but write different code in method or assign different value to properties.
Example: created hello() method in the parent class that is returning string "Hey". Now after override this hello() method in child class, it is returning a different string "Hello". To override this hello() method name must be same as of parent class method name.

Here is the code:

// The parent class has hello method that returns "Hey".
class Car {
  public function hello() {
    return "Hey";
  }
}

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

Result: Hello

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

Prevent overriding the parent' methods by child class

To prevent overriding method of parent class in the child class, use "final" keyword. prefix "final" keyword in the parent method.

Example: I have declared hello() method as final in parent class and still try to override it in the child class. What will happen?
Or what will happen when we try to override a final method?

// The parent class has hello method that returns "Hey".

class Car {
  final public function hello() {
    return "Hey";
  }
}

//The child class has hello method that tries to override the hello method in the parent
class SportsCar extends Car {
  public function hello() {
    return "Hello";
  }
}

//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.

No comments:

Post a Comment