Scripting LanguageUnit 710 min read
OOP in PHP: Classes, Inheritance, Polymorphism, Interfaces & Abstract Classes
Unit 7 of Scripting Language covers PHP’s object-oriented programming (OOP) features—classes, inheritance, polymorphism, interfaces, and abstract classes—with real-world applications, code examples, and exam-focused traces of how these concepts work under the hood.
TAKEAWAYS:
- PHP OOP uses classes (blueprints) and objects (instances) to organize code into reusable, modular components, mimicking real-world relationships (e.g., a
BankAccountclass withdeposit()andwithdraw()methods). - Inheritance lets child classes reuse parent class properties/methods (e.g.,
SavingsAccountinheriting fromBankAccount), reducing redundancy and enforcing a hierarchy likeAnimal → Dog → Labrador. - Polymorphism enables methods to behave differently based on the object (e.g.,
calculateArea()forCirclevs.Square), visualized via method overriding or interfaces. - Abstract classes and interfaces define contracts (e.g.,
Shapeabstract class forcingcalculateArea()), ensuring consistency across unrelated classes likeRectangleandTriangle. - Real-world PHP OOP appears in eSewa’s payment processing (inheritance for
PaymentMethod→KhaltiPayment), Ncell’s billing system (polymorphism forDiscounttypes), and Nepal Stock Exchange (NEPSE) data validation (interfaces forDataValidator). - Exam questions test code implementation (e.g., overriding, interfaces) and conceptual differences (e.g., abstract vs. interface), so trace variable states and method calls step-by-step.
Core Concepts of OOP in PHP
1. Classes and Objects: The Building Blocks
Definition: A class is a blueprint for objects, defining properties (attributes) and methods (functions). An object is an instance of a class. Example:
class BankAccount {
public $accountNumber;
public $balance;
public function deposit($amount) {
$this->balance += $amount;
}
public function withdraw($amount) {
if ($amount <= $this->balance) {
$this->balance -= $amount;
}
}
}
$myAccount = new BankAccount(); // Object creation
$myAccount->deposit(1000);
Visual Trace:
| Step | myAccount State |
Action |
|---|---|---|
| Initialization | accountNumber: null, balance: 0 |
new BankAccount() |
| After deposit(1000) | accountNumber: null, balance: 1000 |
$myAccount->deposit(1000) |
Real-World Analogy:
- eSewa’s
Userclass has properties likeuserId,email, and methods likelogin()orupdateProfile(). Each user (e.g., "user123") is an object of this class.
2. Inheritance: Code Reusability
Definition: Inheritance allows a child class to inherit properties/methods from a parent class, promoting DRY (Don’t Repeat Yourself) code. Example:
class Vehicle {
public $brand;
public function displayBrand() {
echo $this->brand;
}
}
class Car extends Vehicle {
public $model;
}
$myCar = new Car();
$myCar->brand = "Toyota";
$myCar->model = "Corolla";
$myCar->displayBrand(); // Output: Toyota
Visual Hierarchy:
classDiagram
class Vehicle {
+brand: string
+displayBrand()
}
class Car {
+model: string
}
Vehicle <|-- Car : InheritsReal-World Use:
- Pathao’s
Vehicleclass (parent) hascalculateFare(), inherited byBikeandCarchild classes, each overridingcalculateFare()based on distance and vehicle type.
3. Polymorphism: One Interface, Many Forms
Types:
- Method Overriding: Child class redefines a parent method.
- Method Overloading: PHP doesn’t support it natively (use variable arguments).
- Interfaces: Contracts for classes to implement methods.
Example (Overriding):
class Shape {
public function calculateArea() {
return 0;
}
}
class Circle extends Shape {
public $radius;
public function calculateArea() {
return 3.14 * $this->radius * $this->radius;
}
}
$circle = new Circle();
$circle->radius = 5;
echo $circle->calculateArea(); // Output: 78.5
Visual State After Override:
| Class | calculateArea() Method |
Output for radius=5 |
|---|---|---|
Shape |
Returns 0 |
0 |
Circle |
Returns 3.14 * r² |
78.5 |
Real-World Use:
- NEPSE’s
Stockclass hascalculateValue(), overridden byEquityStock(shares) andDebtStock(bonds) to compute different valuation formulas.
4. Abstract Classes vs. Interfaces
Comparison Table:
| Feature | Abstract Class | Interface |
|---|---|---|
| Instantiation | Cannot be instantiated (abstract) |
Cannot be instantiated |
| Properties | Can have properties (with values) | Cannot have properties |
| Methods | Can have abstract and concrete methods | Only abstract methods |
| Inheritance | Single inheritance | Multiple inheritance allowed |
| Use Case | Shared code + partial implementation | Contract for unrelated classes |
Example (Abstract Class):
abstract class Animal {
abstract public function makeSound();
public function sleep() {
echo "Zzz...";
}
}
class Dog extends Animal {
public function makeSound() {
echo "Bark!";
}
}
Example (Interface):
interface Logger {
public function log($message);
}
class FileLogger implements Logger {
public function log($message) {
file_put_contents("log.txt", $message);
}
}
Visual Contract:
classDiagram
class Logger {
<<interface>>
+log(message: string)
}
class FileLogger {
+log(message: string)
}
Logger <|.. FileLogger : ImplementsReal-World Use:
- Khalti’s
PaymentGatewayinterface definesprocessPayment(), implemented byKhaltiProcessorandEsewaProcessorclasses.
5. Access Modifiers: Controlling Visibility
PHP uses public, protected, and private to restrict access:
- Public: Accessible everywhere.
- Protected: Accessible within class and child classes.
- Private: Accessible only within the class.
Example:
class User {
private $password;
protected $email;
public $name;
public function setPassword($pass) {
$this->password = $pass; // Private access
}
}
Visual Access Rules:
mindmap
root((Access Modifiers))
public
protected
privateWorked Example: Bank Loan System
Scenario:
Design a system where Loan is an abstract class with calculateInterest(), overridden by HomeLoan and CarLoan classes. Use inheritance and polymorphism.
Code:
abstract class Loan {
protected $principal;
abstract public function calculateInterest();
}
class HomeLoan extends Loan {
public function calculateInterest() {
return $this->principal * 0.08; // 8% interest
}
}
class CarLoan extends Loan {
public function calculateInterest() {
return $this->principal * 0.12; // 12% interest
}
}
// Usage
$homeLoan = new HomeLoan();
$homeLoan->principal = 500000;
echo $homeLoan->calculateInterest(); // Output: 40000
Trace Table:
| Class | principal |
calculateInterest() |
Output |
|---|---|---|---|
Loan |
N/A | Abstract | N/A |
HomeLoan |
500,000 | 500000 * 0.08 |
40,000 |
CarLoan |
300,000 | 300000 * 0.12 |
36,000 |
Real-World Tie:
- Nepal Bank Limited’s loan system uses this structure:
Loan(abstract) →HomeLoan/CarLoan(concrete), with interest rates dynamically calculated based on loan type.
Common Pitfalls and Best Practices
- Avoid Deep Inheritance Hierarchies: Prefer composition over deep inheritance (e.g., use
has-ainstead ofis-awhere possible). - Use Interfaces for Unrelated Classes: Example:
Serializableinterface forUserandProductclasses. - Document Abstract Methods: Clearly state what child classes must implement (e.g.,
@method calculateArea()inShape). - Leverage Type Hinting: Ensure methods accept correct types (e.g.,
public function setAge(int $age)).
In the Real World
eSewa’s Payment Processing:
- Concept: Inheritance and Polymorphism.
- How: The
PaymentMethodabstract class definesprocessPayment(), implemented by child classes likeKhaltiPayment(overrides with Khalti API calls) andCreditCardPayment(overrides with card validation). Polymorphism allows eSewa to callprocessPayment()generically, handling any payment type.
Pathao’s Ride Fare Calculation:
- Concept: Method Overriding.
- How: The
Vehicleclass hascalculateFare(), overridden byBike(flat rate + distance) andCar(distance × base rate). When a user books a ride, Pathao’s system callscalculateFare()on the vehicle object, dynamically computing the correct fare.
NEPSE’s Stock Data Validation:
- Concept: Interfaces.
- How: The
DataValidatorinterface enforcesvalidate()andformat()methods.EquityValidatorandDebtValidatorimplement these, ensuring all stock data adheres to NEPSE’s rules before processing trades.
Exam Tip
Code Implementation Questions:
- Always trace variable states after each method call (e.g., show
$object->propertyvalues before/after operations). - For inheritance, explicitly state parent-child relationships in comments (e.g.,
// Car extends Vehicle).
- Always trace variable states after each method call (e.g., show
Conceptual Differences:
- Abstract vs. Interface: Abstract classes provide partial implementation; interfaces are pure contracts. Example:
- Abstract:
Animalwithsleep()implemented,makeSound()abstract. - Interface:
Loggerwith onlylog()declared.
- Abstract:
- Overriding vs. Overloading: PHP doesn’t support overloading natively. Use variable arguments (
...$args) or default parameters instead.
- Abstract vs. Interface: Abstract classes provide partial implementation; interfaces are pure contracts. Example:
Real-World Scenarios:
- Link answers to Nepali tech companies (e.g., "Like Pathao’s fare system, this uses polymorphism to handle different vehicle types").
- For CRUD operations, show SQL queries alongside PHP code (e.g.,
INSERT INTO users VALUES (...)).
Common Exam Patterns:
- Design a form + validate + store: Use
isset()/empty()for validation,PDOfor database operations. - CRUD Operations: Implement
create(),read(),update(),delete()methods in a class (e.g.,UserManager).
- Design a form + validate + store: Use
Pro Tip: For questions like "Write a PHP program to handle method overriding", include:
- A parent class with a method.
- A child class overriding it.
- A trace table showing method behavior before/after override.
- A real-world analogy (e.g., "Like Ncell’s billing system overrides base rates for loyal customers").
Based on the TU BCA syllabus for Scripting Language (CACS254), unit 7.
Discussion
Loading…