Inheritance in PHP

To implement the idea of reusability, you need to learn the process of acquiring the properties of objects of one class (parent class) using the objects of another class (child class). Hence, inheritance is the process of deriving one class from a base class (the parent class) and the derived class (a child class or subclass).

images/articles/php/inheritance-in-php.jpg

Inheritance allows a class to acquire the members of another class. Inheritance supports the flow of information in a hierarchical way to the derived objects so that, along with the inherited properties, the derived class can add its own properties. Again, such a derived class can be inherited by another and so on.

For example, the Square class inherits from Rectangle, specified by the extends keyword. Rectangle then becomes the parent class of Square, which in turn becomes a child class of Rectangle. In addition to its own members, Square gains all accessible (non-private) members in Rectangle, including any constructor.

// Parent class (base class)
class Rectangle
{
public $x, $y;
function __construct($a, $b)
{
$this->x = $a;
$this->y = $b;
}
}

PHP uses the extends keyword to inherit from a parent class. PHP supports single inheritance, meaning a class can inherit from a single class.

// Child class (derived class)
class Square extends Rectangle
{

}

When creating an instance of Square, two arguments must now be specified because the class Square has inherited the class Rectangle’s constructor.

$s = new Square(5, 10);

The properties inherited from Rectangle can also be accessed from the Square object.

$s->x = 5; $s->y = 10;

So, the properties from the parent class can be reused in the derived object. While deriving, you can add additional members and use the parent members as well.

Overriding Members

A member in a child class can redefine a member in its parent class to give it a new implementation. To override an inherited member, it just needs to be re-declared with the same name.

class Square extends Rectangle
{
function __construct($a)
{
$this->x = $a;
$this->y = $a;
}
}

With this new constructor, only a single argument is used to create the Square.

$s = new Square(5);

Because the inherited constructor of Rectangle is overridden, Rectangle's constructor is no longer called when the Square object is created. It is up to the developer to call the parent constructor, if necessary. This is done by the parent keyword and a double colon. The double colon is known as the scope resolution operator (::).

class Square extends Rectangle
{
function __construct($a)
{
parent::__construct($a,$a);
}
}

Final Keyword

To stop a child class from overriding a method, it can be defined as final. A class itself can also be defined as final to prevent any class from extending it.

final class NotExtendable
{
final function notOverridable() {}
}

Instanceof Operator

As a safety precaution, you can test to see whether an object can be cast to a specific class by using the instanceof operator. This operator returns true if the left side object can be cast into the right side type without causing an error. This is true when the object is an instance of, or inherits from, the right-side class.

$s = new Square(5);
$s instanceof Square; // true
$s instanceof Rectangle; // true

Access Levels

Every class member has an accessibility level that determines where the member is visible. There are three of them available in PHP: public, protected, and private.

class MyClass
{
public $myPublic; // unrestricted access
protected $myProtected; // enclosing or child class
private $myPrivate; // enclosing class only
}

Unlike properties, methods do not have to have an explicit access level specified. They default to public access unless set to another level.

As a guideline , when choosing an access level, it is generally best to use the most restrictive level possible. This is because the more places a member can be accessed, the more places it can be accessed incorrectly, which makes the code harder to debug. Using restrictive access levels also makes it easier to modify the class without breaking the code for any other developers using that class.

1. Private Access

All members, regardless of access level, are accessible in the class in which they are declared - the enclosing class. This is the only place where a private member can be accessed.

class MyClass
{
public $myPublic = 'public';
protected $myProtected = 'protected';
private $myPrivate = 'private';

function test()
{
echo $this->myPublic; // allowed
echo $this->myProtected; // allowed
echo $this->myPrivate; // allowed
}
}

2. Protected Access

A protected member can be accessed from inside the child or the parent classes, as well as from within the enclosing class.

class MyChild extends MyClass
{
function test()
{
echo $this->myPublic; // allowed
echo $this->myProtected; // allowed
echo $this->myPrivate; // inaccessible
}
}

3. Public Access

Public members have unrestricted access. In addition to anywhere a protected member can be accessed, a public member can also be reached through an object variable.

$m = new MyClass();
echo $m->myPublic; // allowed
echo $m->myProtected; // inaccessible
echo $m->myPrivate; // inaccessible

If no access modifiers are mentioned before a method, then it will be considered public by default.