オブジェクトとの違い

列挙型はクラスやオブジェクトの上に構築されていますが、 オブジェクトに関連する機能を全てサポートしているわけではありません。 特に、列挙型では状態を持つことが禁止されています。

  • コンストラクタやデストラクタは禁止されています。
  • 継承はサポートされていません。列挙型は継承できませんし、何かを継承されることもありません。
  • staticまたはオブジェクトのプロパティは許可されていません。
  • 列挙型の case を clone することはサポートされていません。なぜなら、case はシングルトンインスタンスでなければならないからです。
  • 以下に示すもの以外の マジックメソッド は許可されていません。
  • 列挙型は、常に使う前に宣言しておかなければなりません。

以下のオブジェクトの機能は利用可能ですし、 他のオブジェクトと同じ振る舞いをします:

  • public, private, protected メソッド
  • public, private, protected な static メソッド
  • public, private, protected な定数
  • 列挙型は、任意の数のインターフェイスを実装できます。
  • 列挙型と case には、 アトリビュート を付加することができます。 TARGET_CLASS ターゲットフィルタには、 列挙型そのものも含まれます。 TARGET_CLASS_CONST ターゲットフィルタには、 列挙型の case も含まれます。
  • マジックメソッド __call, __callStatic, __invoke
  • マジック定数 __CLASS____FUNCTION__ は、通常通り動作します。

マジック定数 ::class を列挙型で使うと、 任意の名前空間を含んだ型の名前として評価されます。 これはオブジェクトと全く同じです。 case インスタンスにおける ::class も、 列挙型として評価されます。これは、その型のインスタンスの場合と同じです。

さらに、列挙型の case は new を使って直接インスタンス化できませんし、 ReflectionClass::newInstanceWithoutConstructor を使っても同様です。 これらは両方、エラーになります。

<?php

$clovers = new Suit();
// Error: Cannot instantiate enum Suit

$horseshoes = (new ReflectionClass(Suit::class))->newInstanceWithoutConstructor()
// Error: Cannot instantiate enum Suit
?>