Interface and Abstract class in PHP

Since interface has been introduced in PHP, there have been various views on when to use interface and when to use abstract classes. Understanding the difference between Interface and Abstract classes will help to write better code.

Interface

Interfaces are used when you need to enforce a class to implement specific operations (methods) and hiding that implementation in the concrete class and exposing only the signature of the operations.

Interface in PHP is defined using the interface keyword. All the methods inside the interface should only be declared and not defined. The definition of the methods must be in the class that implements this interface using the implements keyword. If the class that implements the interface does not define all the methods specified in the interface, then an error is thrown.

Remember the following when using interface

  • All the methods in interface must have Public Visibility
  • One interface can extend another interface without defining the methods of the extended interface
  • A class can implement multiple interfaces unlike extending a class where only one class can be extended.

Syntax

interface interfaceName {
  // interface methods. Must only be declared and must be public
}

Example

<?php
/**
 * Defines the interface that must be implemented by the
 * Database class that implements the session handling.
 */
interface SessionDBInterface {
  /**
   * Read the data corresponding to the $sessionId from the session database
   *
   * @param type $sessionId Id of the session to which data must be read
   * @return string|boolean
   */
  public function readSessionData($sessionId);
  /**
   * Writes the given session data to the session database.
   *
   * @param type $sessionId
   * @param type $sessionData
   */
  public function writeSessionData($sessionId, $sessionData);
  /**
   * Deletes the session data for the given sessionId from the database.
   *
   * @param type $sessionId
   * @return boolean
   */
  public function deleteSessionData($sessionId);
  /**
   * Check if a session for the current $sessionId exists.
   *
   * @param type $sessionId
   * @return boolean
   */
  public function checkSession($sessionId);
}

The above is an example of how interface must be implemented. The SessionDBInterface declares the operations required to implement the Sessions storage in database. The class that implements this interface must implement all the methods defined in this interface.

Constants

Interface can also have constants like concrete classes, but constants in interface cannot be overridden by the class/interface that implements the interface.

PHP contains some Pre-defined Interfaces that you can use.

Abstract

Abstract class is used when we need to have some common operations which apply to all the concrete classes that extend the abstract class. Abstract classes can also enforce the concrete class to implement a specific operation by declaring abstract method.

By defining abstract classes you can define common operations for specific concrete classes that extend this abstract class. The following things should be remembered when using abstract classes,

  • Abstract classes cannot be instantiated. Doing so will yield an error.
  • Any class that contains at least one abstract method should be an abstract class.
  • Abstract methods should not be defined, they should only be declared.
  • Concrete class extending the abstract class must define all the abstract methods specified.
  • The method definition in the concrete class must contain the same visibility as in the abstract class or a less visibility. Private > Protected > Public.
  • The signature (i.e. the params) of the methods must also match the signature specified in the abstract class methods. Which includes the type hints e.g. ..(array $config, User $user) and number of arguments.

Syntax

abstract class className {
  // some common methods.
  // abstract methods that should be implemented in the child class.
}

Example

abstract class Fruit {
  // Common methods of fruit
  public function plantSeed() {
    echo 'Seed is planted' . PHP_EOL;
  }
  
  public function grow() {
    echo 'Fruit is growing' . PHP_EOL;
  }
  
  // Methods of specific fruit
  
  public abstract function showColor();
  public abstract function getTaste();
}

class Apple extends Fruit {

  public function showColor() {
    echo 'Color of Apple is Red' . PHP_EOL;
  }
  
  public function getTaste() {
    echo 'Taste of apple is Sweet' . PHP_EOL;
  }
}

class Lemon extends Fruit {

  public function showColor() {
    echo 'Color of Lemon is Yellow' . PHP_EOL;
  }
  
  public function getTaste() {
    echo 'Taste of Lemon is Sour' . PHP_EOL;
  }
}

$apple = new Apple();
$apple->plantSeed();
$apple->grow();
$apple->showColor();
$apple->getTaste();

$lemon = new Lemon();
$lemon->plantSeed();
$lemon->grow();
$lemon->showColor();
$lemon->getTaste();

Output
Output(executed with HHVM)

The above example shows how abstract class can be used. This might not actually resemble the real world scenario, but i hope you get the point.

Apple and Lemon has access to the plantSeed() and grow() common methods defined inside the abstract class. Also it implements the abstract methods defined in it.