Skip to main content
FAQ Component
Question
Can you explain the four main principles of Object-Oriented Programming (OOP) and give an example of how you’ve applied each in PHP?
Answer

The four main principles of Object-Oriented Programming (OOP) are Encapsulation, Inheritance, Polymorphism, and Abstraction. Here’s a breakdown of each principle along with examples of how they can be applied in PHP:

1. Encapsulation

Encapsulation is the concept of restricting direct access to certain details of an object and only exposing what is necessary. This is achieved using access modifiers like private, protected, and public.

Example in PHP

class BankAccount {
    private $balance;

    public function __construct($initialBalance) {
        $this->balance = $initialBalance;
    }

    public function deposit($amount) {
        $this->balance += $amount;
    }

    public function getBalance() {
        return $this->balance;
    }
}

$account = new BankAccount(1000);
$account->deposit(500);
echo $account->getBalance(); // Outputs: 1500
  • Here, $balance is private, preventing direct modification.
  • Methods deposit() and getBalance() act as controlled access points.

 

2. Inheritance

Inheritance allows a class to inherit properties and methods from another class, promoting code reusability.

Example in PHP

class Vehicle {
    protected $brand;

    public function __construct($brand) {
        $this->brand = $brand;
    }

    public function getBrand() {
        return $this->brand;
    }
}

class Car extends Vehicle {
    private $model;

    public function __construct($brand, $model) {
        parent::__construct($brand);
        $this->model = $model;
    }

    public function getCarInfo() {
        return "Brand: " . $this->getBrand() . ", Model: " . $this->model;
    }
}

$car = new Car("Toyota", "Corolla");
echo $car->getCarInfo(); // Outputs: Brand: Toyota, Model: Corolla

Car inherits from Vehicle, reusing its methods and properties.

 

3. Polymorphism

Polymorphism allows objects of different classes to be treated as objects of a common base class. This is typically achieved using method overriding or interfaces.

Example in PHP

interface Animal {
    public function makeSound();
}

class Dog implements Animal {
    public function makeSound() {
        return "Bark";
    }
}

class Cat implements Animal {
    public function makeSound() {
        return "Meow";
    }
}

function animalSound(Animal $animal) {
    echo $animal->makeSound();
}

$dog = new Dog();
$cat = new Cat();

animalSound($dog); // Outputs: Bark
animalSound($cat); // Outputs: Meow

The makeSound() method is implemented differently in Dog and Cat, but they are treated as Animal objects.

 

4. Abstraction

Abstraction hides implementation details and only exposes essential functionalities.

Example in PHP

abstract class Payment {
    abstract public function processPayment($amount);
}

class CreditCardPayment extends Payment {
    public function processPayment($amount) {
        return "Processing Credit Card payment of $" . $amount;
    }
}

class PayPalPayment extends Payment {
    public function processPayment($amount) {
        return "Processing PayPal payment of $" . $amount;
    }
}

$payment = new CreditCardPayment();
echo $payment->processPayment(100); // Outputs: Processing Credit Card payment of $100

The Payment class defines an abstract method processPayment(), which is implemented differently by CreditCardPayment and PayPalPayment.

 

Summary

OOP PrincipleDescriptionExample
EncapsulationRestricting direct access to object propertiesPrivate $balance in BankAccount
InheritanceReusing properties/methods of a parent classCar extends Vehicle
PolymorphismSame interface, different implementationsDog and Cat implement Animal
AbstractionHiding implementation detailsPayment class with processPayment()

 

Question
How does inheritance work in PHP, and how have you utilized it in Drupal modules?
Answer

How Inheritance Works in PHP

Inheritance in PHP allows one class (child class) to inherit properties and methods from another class (parent class). This promotes code reusability and maintainability.

Basic Example in PHP

class ParentClass {
    protected $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function greet() {
        return "Hello, my name is " . $this->name;
    }
}

class ChildClass extends ParentClass {
    private $age;

    public function __construct($name, $age) {
        parent::__construct($name); // Calling parent constructor
        $this->age = $age;
    }

    public function introduce() {
        return $this->greet() . " and I am " . $this->age . " years old.";
    }
}

$child = new ChildClass("John", 25);
echo $child->introduce(); // Outputs: Hello, my name is John and I am 25 years old. 
  • The ChildClass inherits greet() from ParentClass, avoiding redundant code.
  • The parent::__construct() function ensures that the parent’s constructor logic is also executed.

How I’ve Used Inheritance in Drupal Modules

In Drupal module development, inheritance is commonly used when:

  • Extending core classes.
  • Creating custom plugin classes.
  • Implementing reusable functionality in service classes.

Example 1: Extending a Core Drupal Controller

When creating a custom controller, extending ControllerBase provides access to Drupal services.

namespace Drupal\custom_module\Controller;

use Drupal\Core\Controller\ControllerBase;

class CustomController extends ControllerBase {
    public function content() {
        return [
            '#markup' => $this->t('Hello, this is a custom controller!'),
        ];
    }
}
  • CustomController inherits helper methods like $this->t() from ControllerBase.

Example 2: Extending a Form Class

When creating custom forms, extending FormBase or ConfigFormBase ensures compliance with Drupal's Form API.

namespace Drupal\custom_module\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class CustomForm extends FormBase {
    public function getFormId() {
        return 'custom_form';
    }

    public function buildForm(array $form, FormStateInterface $form_state) {
        $form['message'] = [
            '#type' => 'textfield',
            '#title' => $this->t('Enter a message'),
        ];

        $form['submit'] = [
            '#type' => 'submit',
            '#value' => $this->t('Submit'),
        ];

        return $form;
    }

    public function submitForm(array &$form, FormStateInterface $form_state) {
        \Drupal::messenger()->addMessage($this->t('You entered: @message', ['@message' => $form_state->getValue('message')]));
    }
}
  • CustomForm extends FormBase, inheriting buildForm(), validateForm(), and submitForm().

Example 3: Extending a Plugin Class

When defining custom block plugins, extending BlockBase ensures adherence to Drupal’s block system.

namespace Drupal\custom_module\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
 * Provides a 'Custom Block'.
 *
 * @Block(
 *   id = "custom_block",
 *   admin_label = @Translation("Custom Block")
 * )
 */
class CustomBlock extends BlockBase {
    public function build() {
        return [
            '#markup' => $this->t('This is a custom block!'),
        ];
    }
}
  • CustomBlock extends BlockBase, inheriting essential block functionalities.

Key Takeaways

Use CaseParent ClassChild Class
Custom ControllerControllerBaseCustomController
Custom FormFormBaseCustomForm
Custom BlockBlockBaseCustomBlock
Question
How do you implement interfaces and abstract classes in PHP, and when would you choose one over the other?
Answer

Implementing Interfaces and Abstract Classes in PHP

Both interfaces and abstract classes in PHP define a structure for classes but differ in key ways. Below, I'll explain their differences, how to implement them, and when to use each.


1. Abstract Classes

An abstract class can have both abstract (unimplemented) methods and regular (implemented) methods. It cannot be instantiated directly and must be extended by child classes.

Example in PHP

abstract class Payment {
    protected $amount;

    public function __construct($amount) {
        $this->amount = $amount;
    }

    // Abstract method (must be implemented by child classes)
    abstract public function processPayment();

    // Concrete method (already implemented)
    public function getAmount() {
        return $this->amount;
    }
}

class CreditCardPayment extends Payment {
    public function processPayment() {
        return "Processing credit card payment of $" . $this->amount;
    }
}

$payment = new CreditCardPayment(100);
echo $payment->processPayment();  // Outputs: Processing credit card payment of $100 

Key Features of Abstract Classes

✅ Can have both abstract and concrete methods.
✅ Can define properties (like $amount).
✅ Supports constructor inheritance.
✅ Used when multiple related classes share common behavior.


2. Interfaces

An interface defines only method signatures, and any class that implements the interface must provide implementations for all the methods.

Example in PHP

interface PaymentGateway {
    public function processPayment($amount);
}

class PayPalPayment implements PaymentGateway {
    public function processPayment($amount) {
        return "Processing PayPal payment of $" . $amount;
    }
}

class StripePayment implements PaymentGateway {
    public function processPayment($amount) {
        return "Processing Stripe payment of $" . $amount;
    }
}

$paypal = new PayPalPayment();
echo $paypal->processPayment(200);  // Outputs: Processing PayPal payment of $200 

Key Features of Interfaces

Only method declarations (no properties or concrete methods).
✅ A class can implement multiple interfaces (PHP does not support multiple inheritance).
✅ Used to enforce consistent behavior across multiple unrelated classes.


When to Choose Abstract Classes vs. Interfaces

FeatureAbstract ClassInterface
Can have concrete methods?✅ Yes❌ No
Can have properties?✅ Yes❌ No
Supports multiple inheritance?❌ No✅ Yes (via multiple interfaces)
When to use?When classes share common behavior and propertiesWhen unrelated classes need to follow the same structure

Usage in Drupal Modules

Example 1: Using an Abstract Class in a Drupal Service

In Drupal services, abstract classes help define reusable logic.

namespace Drupal\custom_module\Service;

abstract class LoggerService {
    protected $logType;

    public function __construct($logType) {
        $this->logType = $logType;
    }

    abstract public function log($message);

    public function getLogType() {
        return $this->logType;
    }
}

class FileLogger extends LoggerService {
    public function log($message) {
        \Drupal::logger($this->logType)->notice($message);
    }
}
  • Here, LoggerService provides a common structure for loggers.
  • FileLogger implements the log() method.

Example 2: Using an Interface for a Custom Drupal Plugin

Interfaces are commonly used in Drupal plugins to ensure a common structure.

namespace Drupal\custom_module\Plugin;

interface CustomProcessorInterface {
    public function process($data);
}

class CSVProcessor implements CustomProcessorInterface {
    public function process($data) {
        // Process CSV data
        return "Processing CSV data: " . json_encode($data);
    }
}

class JSONProcessor implements CustomProcessorInterface {
    public function process($data) {
        // Process JSON data
        return "Processing JSON data: " . json_encode($data);
    }
}
  • Different processors (CSV, JSON) implement the same interface but behave differently.
  • This ensures consistency and flexibility across processors.

Final Thoughts

✅ Use Abstract Classes when different classes share common properties and behavior.
✅ Use Interfaces when different classes must follow the same structure but may not be related.

Tag
OOPS