PHP枚举方法

2024-01-03 66

在PHP中,枚举类型是一种非常强大的数据类型,它允许我们定义一组命名的常量。这些常量可以包含方法,也可以实现接口。如果枚举实现了接口,那么其中的条目也能接受接口的类型检测。此外,枚举类型还提供了一些静态方法,这些方法可以在不创建枚举实例的情况下调用。

一、枚举方法

枚举(包括纯粹枚举、回退枚举)还能包含方法, 也能实现 interface。 如果 Enum 实现了 interface,则其中的条目也能接受 interface 的类型检测。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?<a href="https://www.zzbaike.com/tag/php" title="查看所有文章关于 php" target="_blank">php</a>
interface Colorful
{
public function color(): string;
}
enum Suit implements Colorful
{
case Hearts;
case Diamonds;
case Clubs;
case Spades;
// 满足 interface 契约。
public function color(): string
{
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
// 不是 interface 的一部分;也没问题
public function shape(): string
{
return "Rectangle";
}
}
function paint(Colorful $c) { ... }
paint(Suit::Clubs); // 正常
print Suit::Diamonds->shape(); // 输出 "Rectangle"
?>
<?<a href="https://www.zzbaike.com/tag/php" title="查看所有文章关于 php" target="_blank">php</a> interface Colorful { public function color(): string; } enum Suit implements Colorful { case Hearts; case Diamonds; case Clubs; case Spades; // 满足 interface 契约。 public function color(): string { return match($this) { Suit::Hearts, Suit::Diamonds => 'Red', Suit::Clubs, Suit::Spades => 'Black', }; } // 不是 interface 的一部分;也没问题 public function shape(): string { return "Rectangle"; } } function paint(Colorful $c) { ... } paint(Suit::Clubs); // 正常 print Suit::Diamonds->shape(); // 输出 "Rectangle" ?>
<?php
interface Colorful
{
    public function color(): string;
}

enum Suit implements Colorful
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;

    // 满足 interface 契约。
    public function color(): string
    {
        return match($this) {
            Suit::Hearts, Suit::Diamonds => 'Red',
            Suit::Clubs, Suit::Spades => 'Black',
        };
    }

    // 不是 interface 的一部分;也没问题
    public function shape(): string
    {
        return "Rectangle";
    }
}

function paint(Colorful $c) { ... }

paint(Suit::Clubs);  // 正常

print Suit::Diamonds->shape(); // 输出 "Rectangle"
?>

在这例子中,Suit 所有的四个实例具有两个方法: color()、shape()。 目前的调用代码和类型检查,和其他对象实例的行为完全一致。

在回退枚举中,interface 的声明紧跟回退类型的声明之后。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
interface Colorful
{
public function color(): string;
}
enum Suit: string implements Colorful
{
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
// 满足 interface 的契约。
public function color(): string
{
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
}
?>
<?php interface Colorful { public function color(): string; } enum Suit: string implements Colorful { case Hearts = 'H'; case Diamonds = 'D'; case Clubs = 'C'; case Spades = 'S'; // 满足 interface 的契约。 public function color(): string { return match($this) { Suit::Hearts, Suit::Diamonds => 'Red', Suit::Clubs, Suit::Spades => 'Black', }; } } ?>
<?php
interface Colorful
{
    public function color(): string;
}

enum Suit: string implements Colorful
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';

    // 满足 interface 的契约。
    public function color(): string
    {
        return match($this) {
            Suit::Hearts, Suit::Diamonds => 'Red',
            Suit::Clubs, Suit::Spades => 'Black',
        };
    }
}
?>

在方法中,定义了 $this 变量,它引用到了条目实例。方法中可以任意复杂,但一般的实践中,往往会返回静态的值, 或者为 $this match 各种情况并返回不同的值。

注意:在本示例中,更好的数据模型实践是再定一个包含 Red 和 Black 枚举值的 SuitColor 枚举,并且返回它作为代替。 然而这会让本示例复杂化。

以上的层次在逻辑中类似于下面的 class 结构(虽然这不是它实际运行的代码):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
interface Colorful
{
public function color(): string;
}
final class Suit implements UnitEnum, Colorful
{
public const Hearts = new self('Hearts');
public const Diamonds = new self('Diamonds');
public const Clubs = new self('Clubs');
public const Spades = new self('Spades');
private function __construct(public readonly string $name) {}
public function color(): string
{
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
public function shape(): string
{
return "Rectangle";
}
public static function cases(): array
{
// 不合法的方法,Enum 中不允许手动定义 cases() 方法
// 参考 “枚举值清单” 章节
}
}
?>
<?php interface Colorful { public function color(): string; } final class Suit implements UnitEnum, Colorful { public const Hearts = new self('Hearts'); public const Diamonds = new self('Diamonds'); public const Clubs = new self('Clubs'); public const Spades = new self('Spades'); private function __construct(public readonly string $name) {} public function color(): string { return match($this) { Suit::Hearts, Suit::Diamonds => 'Red', Suit::Clubs, Suit::Spades => 'Black', }; } public function shape(): string { return "Rectangle"; } public static function cases(): array { // 不合法的方法,Enum 中不允许手动定义 cases() 方法 // 参考 “枚举值清单” 章节 } } ?>
<?php
interface Colorful
{
    public function color(): string;
}

final class Suit implements UnitEnum, Colorful
{
    public const Hearts = new self('Hearts');
    public const Diamonds = new self('Diamonds');
    public const Clubs = new self('Clubs');
    public const Spades = new self('Spades');

    private function __construct(public readonly string $name) {}

    public function color(): string
    {
        return match($this) {
            Suit::Hearts, Suit::Diamonds => 'Red',
            Suit::Clubs, Suit::Spades => 'Black',
        };
    }

    public function shape(): string
    {
        return "Rectangle";
    }

    public static function cases(): array
    {
        // 不合法的方法,Enum 中不允许手动定义 cases() 方法
        // 参考 “枚举值清单” 章节
    }
}
?>

尽管 enum 可以包括 public、private、protected 的方法, 但由于它不支持继承,因此在实践中 private 和 protected 效果是相同的。

二、枚举静态方法

枚举也能有静态方法。 在枚举中静态方法主要用于取代构造器,如:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
enum Size
{
case Small;
case Medium;
case Large;
public static function fromLength(int $cm): static
{
return match(true) {
$cm < 50 => static::Small,
$cm < 100 => static::Medium,
default => static::Large,
};
}
}
?>
<?php enum Size { case Small; case Medium; case Large; public static function fromLength(int $cm): static { return match(true) { $cm < 50 => static::Small, $cm < 100 => static::Medium, default => static::Large, }; } } ?>
<?php
enum Size
{
    case Small;
    case Medium;
    case Large;

    public static function fromLength(int $cm): static
    {
        return match(true) {
            $cm < 50 => static::Small,
            $cm < 100 => static::Medium,
            default => static::Large,
        };
    }
}
?>

仅管 enum 可以包括 public、private、protected 的静态方法, 但由于它不支持继承,因此在实践中 private 和 protected 效果是相同的。

  • 广告合作

  • QQ群号:4114653

温馨提示:
1、本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。邮箱:2942802716#qq.com(#改为@)。 2、本站原创内容未经允许不得转裁,转载请注明出处“站长百科”和原文地址。
PHP枚举方法
下一篇: PHP枚举常量