Z
ZHANK
面向对象

Trait 与接口

trait 代码复用、interface 契约、implements、抽象类 abstract

Trait 与接口

PHP 是单继承语言——一个类只能继承一个父类。Trait 和接口填补了多继承的空缺。

学完本章你将: 掌握 trait 代码复用、interface 契约、abstract 抽象类。


Interface —— 定义能做什么

php
<?php
interface LoggerInterface {
    public function log(string $msg): void;
}

interface FormatterInterface {
    public function format(string $msg): string;
}

// 可以同时实现多个接口
class FileLogger implements LoggerInterface, FormatterInterface {
    public function log(string $msg): void {
        file_put_contents("log.txt", $this->format($msg) . "\n", FILE_APPEND);
    }
    public function format(string $msg): string {
        return "[" . date("Y-m-d H:i:s") . "] $msg";
    }
}

Trait —— 横向代码复用

php
<?php
trait Timestampable {
    private DateTime $createdAt;
    private DateTime $updatedAt;

    public function setCreatedAt(): void {
        $this->createdAt = new DateTime();
    }
}

trait SoftDeletable {
    private bool $deleted = false;
    public function softDelete(): void { $this->deleted = true; }
    public function isDeleted(): bool { return $this->deleted; }
}

class Article {
    use Timestampable, SoftDeletable;
}

💡 何时用 Trait vs Interface? Interface 定义"能做什么"(契约);Trait 提供"怎么做"(实现)。两者互补。


抽象类

php
<?php
abstract class Repository {
    abstract public function find(int $id): ?object;
    abstract public function save(object $entity): void;

    public function findOrFail(int $id): object {
        return $this->find($id) ?? throw new Exception("未找到");
    }
}