CodeMIRAI
0 XP

Classes and objects

2 min read 6 runnable examples Quiz included

A class and its objects

PHP
<?php
class Account {
    public string $owner;
    private float $balance = 0;

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

    public function deposit(float $amount): void {
        if ($amount <= 0) {
            throw new InvalidArgumentException("Deposit must be positive");
        }
        $this->balance += $amount;
    }

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

$acct = new Account("Asha");
$acct->deposit(500);
$acct->deposit(250);
echo $acct->owner, " has ", $acct->getBalance(), "\n";
  • new Account("Asha") creates an object and runs __construct.
  • $this->balance is the object's own property, reached with the -> arrow.
  • private means only code inside the class can touch $balance, so it can change only through deposit.

Constructor promotion and readonly (PHP 8)

PHP
<?php
class Product {
    public function __construct(
        public readonly string $name,
        public readonly float $price,
        private int $stock = 0,
    ) {}

    public function inStock(): bool {
        return $this->stock > 0;
    }
}

$p = new Product("Keyboard", 89.99, 40);
echo "$p->name costs $p->price\n";
var_dump($p->inStock());

try {
    $p->price = 1.00;
} catch (Error $e) {
    echo get_class($e), ": ", $e->getMessage(), "\n";
}

Writing a visibility keyword in front of a constructor parameter declares the property and assigns it in one go: constructor promotion. readonly properties can be set once and never changed, as the failed price cut shows.

Static members and constants

PHP
<?php
class Temperature {
    public const ABSOLUTE_ZERO = -273.15;
    private static int $created = 0;

    public static function fromFahrenheit(float $f): float {
        self::$created++;
        return round(($f - 32) * 5 / 9, 1);
    }

    public static function count(): int {
        return self::$created;
    }
}

echo Temperature::ABSOLUTE_ZERO, "\n";
echo Temperature::fromFahrenheit(98.6), "\n";
echo Temperature::fromFahrenheit(212), "\n";
echo Temperature::count(), " conversions\n";

static members belong to the class, not to an object, and are used with ::. Inside the class, self:: refers to the class itself.

Inheritance, interfaces and abstract classes

PHP
<?php
interface Shape {
    public function area(): float;
}

abstract class BaseShape implements Shape {
    public function describe(): string {
        return sprintf("%s with area %.2f", static::class, $this->area());
    }
}

class Circle extends BaseShape {
    public function __construct(private float $r) {}
    public function area(): float { return M_PI * $this->r ** 2; }
}

class Rectangle extends BaseShape {
    public function __construct(private float $w, private float $h) {}
    public function area(): float { return $this->w * $this->h; }
}

$shapes = [new Circle(1), new Rectangle(3, 4)];
foreach ($shapes as $s) {
    echo $s->describe(), "\n";
}
var_dump($shapes[0] instanceof Shape);
  • An interface lists methods a class promises to have; implements makes the promise.
  • An abstract class can't be created with new, and can leave methods for its subclasses to write.
  • extends inherits from a parent class, and parent::method() calls the parent's version of a method you've overridden.

Traits

PHP
<?php
trait HasTimestamps {
    private ?string $updatedAt = null;

    public function touch(): void {
        $this->updatedAt = date("Y-m-d", mktime(0, 0, 0, 7, 1, 2024));
    }

    public function updated(): string {
        return $this->updatedAt ?? "never";
    }
}

class Post { use HasTimestamps; }
class Comment { use HasTimestamps; }

$post = new Post();
echo $post->updated(), "\n";
$post->touch();
echo $post->updated(), "\n";

A trait is a bundle of methods and properties copied into any class that uses it. It shares code between unrelated classes without inheritance. (The fixed date keeps the output the same every time; real code would use the current date.)

Enums (PHP 8.1)

PHP
<?php
enum Status: string {
    case Draft = "draft";
    case Published = "published";
    case Archived = "archived";

    public function label(): string {
        return ucfirst($this->value);
    }
}

$s = Status::from("published");
echo $s->name, " / ", $s->value, " / ", $s->label(), "\n";
var_dump(Status::tryFrom("deleted"));
echo count(Status::cases()), " statuses\n";

An enum is a type with a fixed set of values. Unlike plain strings, a typo like Status::Publshed is an error rather than a silent bug.

Finished this lesson?Mark it complete to earn +20 XP and move your progress on.