<?php
// Parent class
class Animal {
public function __construct(
protected string $name,
protected string $sound
) {}
public function speak(): string {
return "{$this->name} says {$this->sound}!";
}
public function eat(string $food): string {
return "{$this->name} is eating {$food}.";
}
public function __toString(): string {
return "Animal({$this->name})";
}
}
// Child class
class Dog extends Animal {
public function __construct(string $name, private string $breed) {
parent::__construct($name, "Woof"); // parent constructor ခေါ်ရမယ်
}
public function fetch(string $item): string {
return "{$this->name} fetches the {$item}! 🐕";
}
public function getBreed(): string { return $this->breed; }
}
class Cat extends Animal {
public function __construct(string $name, private bool $indoor = true) {
parent::__construct($name, "Meow");
}
public function purr(): string {
return "{$this->name} purrs... 😺";
}
}
$dog = new Dog("Rex", "Labrador");
$cat = new Cat("Mimi");
echo $dog->speak(); // "Rex says Woof!" — inherited
echo $dog->eat("bone"); // "Rex is eating bone." — inherited
echo $dog->fetch("ball"); // "Rex fetches the ball! 🐕" — own method
echo $cat->speak(); // "Mimi says Meow!"
echo $cat->purr(); // "Mimi purrs... 😺"
// instanceof check
var_dump($dog instanceof Dog); // true
var_dump($dog instanceof Animal); // true
var_dump($cat instanceof Dog); // false
<?php
class Shape {
public function __construct(protected string $color = "black") {}
public function area(): float { return 0.0; }
public function describe(): string {
return "A {$this->color} " . get_class($this) .
" with area " . number_format($this->area(), 2);
}
}
class Circle extends Shape {
public function __construct(private float $radius, string $color = "red") {
parent::__construct($color);
}
// Override area()
public function area(): float {
return M_PI * $this->radius ** 2;
}
}
class Rectangle extends Shape {
public function __construct(
private float $width,
private float $height,
string $color = "blue"
) {
parent::__construct($color);
}
public function area(): float {
return $this->width * $this->height;
}
// Override + extend parent method
public function describe(): string {
$parentDesc = parent::describe(); // call parent's method
return $parentDesc . " ({$this->width}x{$this->height})";
}
}
$c = new Circle(5);
$r = new Rectangle(4, 6);
echo $c->describe(); // "A red Circle with area 78.54"
echo $r->describe(); // "A blue Rectangle with area 24.00 (4x6)"
<?php
class Payment {
public function __construct(protected float $amount) {}
public function process(): string { return "Processing payment"; }
public function getAmount(): float { return $this->amount; }
}
class CreditCard extends Payment {
public function process(): string {
$fee = $this->amount * 0.02;
return sprintf("💳 Credit Card: $%.2f (fee: $%.2f)", $this->amount, $fee);
}
}
class PayPal extends Payment {
public function process(): string {
$fee = $this->amount * 0.015;
return sprintf("🔵 PayPal: $%.2f (fee: $%.2f)", $this->amount, $fee);
}
}
class KPay extends Payment {
public function process(): string {
return sprintf("📱 KPay: $%.2f (no fee!)", $this->amount);
}
}
// Polymorphism — same method call, different behavior
$payments = [
new CreditCard(100),
new PayPal(200),
new KPay(150),
];
foreach ($payments as $payment) {
echo $payment->process() . "\n";
// Type hint accepts Payment or any subclass
}
// Type hinting with polymorphism
function processPayment(Payment $p): void {
echo "Total: $" . $p->getAmount() . "\n";
echo $p->process() . "\n";
}
processPayment(new CreditCard(500));
processPayment(new KPay(300));
<?php
// Abstract class = cannot be instantiated directly
// Force child classes to implement specific methods
abstract class Report {
public function __construct(protected string $title) {}
// Abstract method — MUST be implemented by children
abstract public function generate(): string;
abstract public function getFormat(): string;
// Concrete method — children inherit as-is
public function header(): string {
return "=== {$this->title} ({$this->getFormat()}) ===";
}
// Template method pattern
public function render(): string {
return $this->header() . "\n" . $this->generate();
}
}
class PDFReport extends Report {
public function generate(): string {
return "PDF content for: {$this->title}\n[PDF binary data...]";
}
public function getFormat(): string { return "PDF"; }
}
class HTMLReport extends Report {
public function generate(): string {
return "<html><body><h1>{$this->title}</h1></body></html>";
}
public function getFormat(): string { return "HTML"; }
}
class CSVReport extends Report {
public function generate(): string {
return "title,date\n\"{$this->title}\",\"" . date('Y-m-d') . "\"";
}
public function getFormat(): string { return "CSV"; }
}
// new Report("Test"); ❌ Fatal Error — cannot instantiate abstract class
$reports = [
new PDFReport("Sales Report"),
new HTMLReport("Monthly Summary"),
new CSVReport("User Data"),
];
foreach ($reports as $report) {
echo $report->render() . "\n\n";
}
<?php
// final class — cannot be extended
final class Singleton {
private static ?self $instance = null;
private function __construct(private string $config) {}
public static function getInstance(): self {
if (self::$instance === null) {
self::$instance = new self("default");
}
return self::$instance;
}
public function getConfig(): string { return $this->config; }
}
// class ExtendedSingleton extends Singleton {} ❌ Fatal Error
// final method — cannot be overridden in child
class Base {
public function normal(): string { return "can override"; }
final public function locked(): string { return "cannot override!"; }
}
class Child extends Base {
public function normal(): string { return "overridden OK"; }
// public function locked(): string {} ❌ Fatal Error
}
| Keyword | Usage | Description |
|---|---|---|
| extends | class Dog extends Animal | Inherit from parent |
| parent:: | parent::__construct() | Call parent method |
| abstract | abstract class / method | Cannot instantiate, must implement |
| final | final class / method | Cannot extend / override |
| instanceof | $obj instanceof Class | Type check (includes parents) |
| get_class() | get_class($obj) | Get actual class name |
| get_parent_class() | get_parent_class($obj) | Get parent class name |
← PHP 08 | Next: PHP 10 → Interfaces & Abstract →