PHP/クラス
本章では、PHPにおけるオブジェクト指向プログラミングの基礎について説明します。オブジェクト指向は、現代のプログラミング言語で広く採用されているパラダイムであり、PHPでも重要な概念の一つです。
PHPのオブジェクト指向は、バージョン5から導入され、現在ではPHP 8.xまで進化を遂げています。オブジェクト指向プログラミングには、クラス、オブジェクト、継承、ポリモーフィズムなどの概念があり、これらを理解することでより柔軟かつ効率的なプログラムを作成することができます。
本章では、オブジェクト指向の基本的な概念から始め、クラスの定義、オブジェクトの生成、メソッドの呼び出し、継承などを順に説明していきます。また、実際の例を交えて、具体的なプログラムの作成方法を解説します。
オブジェクト指向は、初心者にとっては難しいと感じるかもしれませんが、一度理解してしまえば、より高度なプログラミングを行うことができます。本章を通じて、オブジェクト指向プログラミングについてしっかりと理解し、PHPのプログラミング能力を向上させてください。
PHPのオブジェクト指向

PHPのオブジェクト指向の主な特徴は以下の通りです。
PHPのオブジェクト指向

PHPのオブジェクト指向プログラミングの長所と短所については以下の通りです。
PHPのオブジェクト指向

【長所】
PHPのオブジェクト指向

【短所】
PHPのオブジェクト指向

学習コストが高くなる: オブジェクト指向プログラミングは、手続き型プログラミングに比べて、抽象的な概念が多く登場するため、学習コストが高くなることがあります。
PHPのオブジェクト指向

クラス Hello は、privateアクセス修飾子を持つ$whoプロパティを持ち、__construct()メソッドで初期化されます。__construct()メソッドは、クラスがインスタンス化されたときに呼び出され、引数 $who が渡された場合は、それを$this->who に設定します。引数が渡されない場合は、デフォルトで "World" を設定します。
PHPのオブジェクト指向

greet() メソッドは、インスタンスの $who プロパティを使用して、 "Hello {who}!" というメッセージを表示します。PHP_EOLは、プラットフォームに依存しない改行コードです。
PHPのオブジェクト指向

次に、$helloという名前の Hello クラスのインスタンスを作成し、greet() メソッドを呼び出します。これにより、「Hello World!」が表示されます。次に、$universeという名前の別の Hello クラスのインスタンスを作成し、greet()メソッドを呼び出します。これにより、「Hello Universe!」が表示されます。
PHPのオブジェクト指向

コンストラクターとプロパティは、クラスにおいて重要な役割を果たします。コンストラクターは、インスタンス化されたオブジェクトの初期化を行うためのメソッドであり、プロパティはオブジェクトのデータを表すためのメンバー変数のようなものです。
PHPのオブジェクト指向

アクセス修飾子は、コンストラクターとプロパティのアクセスレベルを定義するために使用されます。アクセス修飾子は、public、private、protectedの3つがあり、それぞれ以下のような意味を持ちます。
PHPのオブジェクト指向

また、プロパティの値を初期化後に変更できないようにするには、readonly修飾子を使用することができます。readonly修飾子は、一度設定された値を変更できないプロパティを定義する場合に便利です。
PHPのオブジェクト指向

これらの修飾子を適切に使うことで、コードの保守性や安全性を高めることができます
PHPのオブジェクト指向

このコードは、PHP 8から導入された、コンストラクター引数にアクセス修飾子を組み合わせてプロパティを定義することができる機能を使用しています。また、readonly修飾子を使用して、値を一度設定した後に変更できないようにプロパティを定義しています。
PHPのオブジェクト指向

具体的には、Hello2クラスでは、コンストラクターの引数として、public修飾子とreadonly修飾子が指定されたwhoという名前のstring型のプロパティを定義しています。コンストラクターでは、このプロパティに初期値が設定されます。greetメソッドは、このプロパティの値を用いて、Helloというメッセージを出力するために使用されます。
PHPのオブジェクト指向

このクラスのインスタンスを生成する際には、コンストラクターに引数を渡すことができます。Hello2のインスタンスを生成する際に引数を渡さない場合、whoプロパティの値は "World" に設定されます。引数を渡した場合は、その値がwhoプロパティに設定されます。
PHPのオブジェクト指向

また、コードの最後の行では、インスタンスが生成された後にプロパティの値を取得し、出力しています。その後、whoプロパティを書き換えようとしている行がコメントアウトされています。これは、readonly修飾子を使用してwhoプロパティが一度設定された後に変更できないようにしているため、エラーが発生します。
PHPのオブジェクト指向

デストラクターとは、オブジェクトが破棄される際に自動的に呼び出される特殊なメソッドです。デストラクターは、クラス定義内に __destruct() という名前で定義されます。デストラクターは、インスタンスを参照する変数が1つもなくなると自動的に呼び出され、そのインスタンスに関連する資源を解放するために使用されます。資源は、メモリ、ファイル、データベース接続など様々です。
PHPのオブジェクト指向

また、readonly 修飾子を使用して、初期値から変更できないプロパティを作成することもできます。以下は、readonly 修飾子を使った例です。
PHPのオブジェクト指向

このコードでは、クラス MyClass のインスタンスが作成され、参照が $obj で保持されます。
PHPのオブジェクト指向

その後、$obj の複製が $o2 に作成され、参照がコピーされます。
PHPのオブジェクト指向

次に、$obj に null が代入されることで、$obj からの参照はなくなりますが、$o2 からの参照は残っています。
PHPのオブジェクト指向

最後に、$o2 に null が代入されることで、すべての参照がなくなります。
PHPのオブジェクト指向

その結果、MyClass::__destruct() が暗黙的に呼び出されます。
PHPのオブジェクト指向

__destruct() は、オブジェクトが破棄される際に自動的に呼び出される特殊なメソッドであり、この例ではクラス名と "done!" という文字列が出力されます。
PHPのオブジェクト指向

PHPには、動的プロパティ(dynamic properties)という機能があります。これは、オブジェクトのプロパティを実行時に定義することができる機能です。しかし、動的プロパティは1つのタイポで意図しないプロパティを作ってしまい、非常に危険であり、プログラムのメンテナンス性を低下させる可能性があります。そのため、PHPでは動的プロパティの使用を非推奨としており、代わりに __get() と __set() メソッドを使用することを推奨しています。
PHPのオブジェクト指向

__get() メソッドは、オブジェクトのプロパティにアクセスする際に、存在しないプロパティにアクセスした場合に呼び出されます。このメソッドを実装することで、存在しないプロパティにアクセスされた場合に特定の処理を行うことができます。
PHPのオブジェクト指向

__set() メソッドは、オブジェクトのプロパティに値を設定する際に、存在しないプロパティに値を設定しようとした場合に呼び出されます。このメソッドを実装することで、存在しないプロパティに値を設定された場合に特定の処理を行うことができます。
PHPのオブジェクト指向

これらのメソッドを使用することで、動的プロパティの使用を避け、プログラムのメンテナンス性を向上させることができます。
PHPのオブジェクト指向

このコードは、クラス Simple を定義し、その中にプロパティ $prop1 を宣言しています。その後、インスタンス $instance を作成し、そのプロパティ $prop1 にアクセスして値を表示し、get_object_vars() 関数を使用して、オブジェクトのプロパティの一覧を表示しています。この結果、$instance->prop1 の値が 1 で、get_object_vars() 関数が $prop1 を返していることがわかります。
PHPのオブジェクト指向

次に、$instance->prop42 というプロパティに値 42 を設定して、その値を表示し、再度 get_object_vars() 関数を使用して、オブジェクトのプロパティの一覧を表示しています。この結果、$instance->prop42 の値が 42 で、get_object_vars() 関数が $prop1 と $prop42 を返していることがわかります。
PHPのオブジェクト指向

このように、PHPでは、既存のプロパティの他に、動的に新しいプロパティを追加することもできます。また、get_object_vars() 関数を使用することで、オブジェクトのプロパティを一覧できます。
PHPのオブジェクト指向

__setと__getは動的プロパティへの代入と参照をインターセプトする特殊関数で、いわゆるアクセサです。
PHPのオブジェクト指向

このコードは、クラス Simple を定義し、その中で __get() メソッドと __set() メソッドを実装しています。
PHPのオブジェクト指向

__get() メソッドは、オブジェクトのプロパティにアクセスする際に、存在しないプロパティにアクセスした場合に呼び出されます。このメソッドを実装することで、存在しないプロパティにアクセスされた場合に特定の処理を行うことができます。この例では、プロパティ名をキーとして配列 $ary から値を取得しています。
PHPのオブジェクト指向

__set() メソッドは、オブジェクトのプロパティに値を設定する際に、存在しないプロパティに値を設定しようとした場合に呼び出されます。このメソッドを実装することで、存在しないプロパティに値を設定された場合に特定の処理を行うことができます。この例では、プロパティ名をキーとして配列 $ary に値を設定しています。
PHPのオブジェクト指向

クラス Simple のインスタンスを作成し、そのプロパティにアクセスすると、__get() メソッドが呼び出されます。最初にアクセスしたプロパティは $prop1 であり、存在するプロパティであるため、その値が表示されます。また、get_object_vars() 関数を使用して、オブジェクトのプロパティを取得し、配列として表示しています。
PHPのオブジェクト指向

次に、存在しないプロパティである $prop42 に値を設定します。このとき、__set() メソッドが呼び出され、配列 $ary に値が設定されます。その後、再び $prop42 にアクセスすると、__get() メソッドが呼び出され、配列 $ary から値が取得され、表示されます。また、get_object_vars() 関数を使用して、オブジェクトのプロパティを取得し、配列として表示しています。このとき、配列 $ary の内容も表示されます。
PHPのオブジェクト指向

object (の公開プロパティ)を array(連想配列)に変換したり、array(連想配列)を object に変換することができます。 これは、「オブジェクトの配列」を使いたい場合、簡素に表現することを可能にします。
PHPのオブジェクト指向

このコードは、配列とオブジェクトの相互変換の例を示しています。
PHPのオブジェクト指向

配列 vect は、3つの要素を持ち、それぞれが name と age というキーを持つハッシュです。最初の foreach ループでは、vect の要素を一つずつ取り出して、array_map 関数を使って各ハッシュのキーと値を連結した文字列を作成し、それを implode 関数を使ってカンマで区切った一つの文字列にまとめて出力しています。
PHPのオブジェクト指向

次に、array_map 関数と無名関数を使って、vect の各要素をオブジェクトに変換しています。このとき、array_map 関数の第二引数に渡している無名関数では、(object) キャストを使って、ハッシュをオブジェクトに変換しています。このようにすることで、各オブジェクトは name プロパティと age プロパティを持つようになります。
PHPのオブジェクト指向

2つ目の foreach ループでは、配列 $objs の各要素を取り出して、name プロパティと age プロパティを連結した文字列を作成し、それを出力しています。最後に、各オブジェクトを array キャストを使って再びハッシュに変換し、キーと値を連結して文字列にして出力しています。
PHPのオブジェクト指向

PHPの object は array と同じくイテレーション可能です。 object は、foreach で反復可能です。
PHPのオブジェクト指向

クラスの継承に当たっては、可視性のコントロールに注意が必要です。
PHPのオブジェクト指向

このコードは、クラスのプロパティにアクセスするために PHP の foreach ループを使用する方法について示しています。
PHPのオブジェクト指向

また、public、protected、private プロパティへのアクセスについても説明しています。
PHPのオブジェクト指向

プロパティ(インスタンス変数)は、それぞれのインスタンスを構成する要素ですが、クラスに属する変数=クラス変数、そしてクラスに属する定数=クラス定数を定義することができます。
PHPのオブジェクト指向

このコードは、クラス定数とクラス変数についての基本的な使い方を示しています。
PHPのオブジェクト指向

まず、クラス Math が定義され、クラス変数 var1 とクラス定数 pi と e が定義されています。var1 は public static で宣言されているため、クラスから直接アクセスできます。また、showVar1() メソッドと setVar1() メソッドがあり、それぞれクラス変数 var1 を参照して更新します。
PHPのオブジェクト指向

まず、Math::$var1 で var1 の値を取得し、それを更新します。次に、showVar1() メソッドを呼び出して、クラス変数 var1 の値を表示し、setVar1() メソッドを使用して値を変更し、再度 showVar1() メソッドを呼び出して、変更された値を表示します。
PHPのオブジェクト指向

次に、クラス定数 pi と e の値を表示し、showPI() メソッドを呼び出して、クラス定数 pi の値を表示します。
PHPのオブジェクト指向

最後に、self キーワードを使用して、クラス変数とクラス定数にアクセスする方法を示しています。self::$var1 でクラス変数にアクセスし、self::pi でクラス定数にアクセスします。これらの値を echo ステートメントで出力します。
PHPのオブジェクト指向

__ からはじまるメソッドは、マジックメソッドといい処理系が特定のタイミングで暗黙に呼出します。 このまでに紹介した、コンストラクターもデストラクターもマジックメソッドです。
PHPのオブジェクト指向

他にも以下のようなマジックメソッドがあります。
PHPのオブジェクト指向

これらのマジックメソッドは、クラス内で実装することができます。マジックメソッドを使うことで、より柔軟なオブジェクト指向プログラミングを行うことができます。ただし、適切に使わないとコードが複雑になってしまう場合もあるので、注意が必要です。
PHPのオブジェクト指向

__toStringは、文字列を必要とする文脈にオブジェクトがあると呼出されます。
PHPのオブジェクト指向

__get() と __set() ChatGPT __get() と __set() は、PHPにおいてマジックメソッドの一種であり、オブジェクトが存在しないプロパティにアクセスしたときに呼び出されます。
PHPのオブジェクト指向

__get() は、存在しないプロパティにアクセスしたときに呼び出され、そのプロパティの値を返すために使用されます。以下は、__get() を使用してプロパティにアクセスする例です。
PHPのオブジェクト指向

__set() は、存在しないプロパティに値を設定しようとしたときに呼び出され、そのプロパティの値を設定するために使用されます。以下は、__set() を使用してプロパティに値を設定する例です。
PHPのオブジェクト指向

上記の例では、MyClassクラスに $data というプロパティがあります。このプロパティは private に宣言されているため、直接アクセスすることはできません。しかし、__get() メソッドを使用することで、存在しないプロパティにアクセスしたときに $data プロパティの値を返すことができます。また、__set() メソッドを使用することで、存在しないプロパティに値を設定し、その値を $data プロパティに保存することができます。
PHPのオブジェクト指向

__get() と __set() は、プロパティを動的に取得または設定するための強力な方法です。しかし、過剰に使用すると、コードの可読性を低下させることがあるため、注意が必要です。
PHPのオブジェクト指向

継承は、既存のクラスを拡張し、新しいクラスを作成するための機能です。継承により、新しいクラスは既存のクラスのプロパティやメソッドを引き継ぐことができます。
PHPのオブジェクト指向

以下の例では、Personクラスを継承したStudentクラスを定義しています。
PHPのオブジェクト指向

Personクラスは、$nameという保護されたプロパティと、__construct()とsayHello()という公開されたメソッドを持っています。__construct()は、インスタンスが作成されたときに実行される特別なメソッドであり、$nameプロパティを初期化します。sayHello()は、$nameプロパティの値を使用してメッセージを出力します。
PHPのオブジェクト指向

Studentクラスは、Personクラスを継承しています。Studentクラスには、$studentIDというプライベートなプロパティと、__construct()とgetStudentID()というパブリックなメソッドがあります。__construct()は、Personクラスの__construct()メソッドを呼び出し、$nameプロパティを初期化し、$studentIDプロパティを設定します。getStudentID()は、$studentIDプロパティの値を返します。
PHPのオブジェクト指向

以下のコードを使用することで、PersonクラスとStudentクラスを使用することができます。
PHPのオブジェクト指向

継承を使用すると、コードの再利用性が向上し、冗長なコードを減らすことができます。 また、継承を使用することで、プログラムの柔軟性が向上します。例えば、新しいクラスを作成する際に、既存のクラスを継承することで、新しいクラスが既存のクラスの機能を引き継ぐことができます。 ただし、継承を過剰に使用すると、コードの複雑さが増し、メンテナンスが困難になる場合があります。継承を使用する際には、適切に設計し、必要な機能だけを継承するように心がけることが重要です。
PHPのオブジェクト指向

抽象クラスとは、具体的な実装が不完全なクラスであり、継承することによってその実装を補完することを目的としたクラスです。抽象クラスは、abstractキーワードを使用して宣言します。抽象クラス自体はインスタンス化することができず、抽象クラスを継承する具象クラスで実装する必要があります。
PHPのオブジェクト指向

以下は、PHPで抽象クラスを定義する例です。
PHPのオブジェクト指向

上記の例では、Animalクラスを抽象クラスとして定義し、makeSound()メソッドを抽象メソッドとして宣言しています。具象クラスであるDogクラスとCatクラスは、Animalクラスを継承しています。DogクラスとCatクラスでは、Animalクラスで宣言された抽象メソッドmakeSound()を具体的に実装しています。
PHPのオブジェクト指向

makeSound()メソッドは、犬が「Woof!」、猫が「Meow!」と鳴くように、各動物の鳴き声を出力します。DogクラスとCatクラスがAnimalクラスを継承しているため、Animalクラスで定義されたコンストラクタも呼び出されます。
PHPのオブジェクト指向

最後に、DogクラスとCatクラスのインスタンスを作成し、makeSound()メソッドを呼び出すことによって、それぞれの動物の鳴き声を出力しています。
PHPのオブジェクト指向

抽象クラスは、多くの具象クラスで共通するプロパティやメソッドを抽出し、再利用可能なコードを作成するのに役立ちます。また、抽象クラスは、継承することで必ず実装しなければならないメソッドを定義することができるため、クラスの機能や振る舞いを制限することができます。これにより、コードの信頼性や保守性を高めることができます。
PHPのオブジェクト指向

例えば、動物クラスを抽象クラスとして定義した場合、多くの動物が鳴き声を出すことができるという共通点を抽出することができます。しかし、どのような鳴き声を出すかは動物によって異なります。そのため、抽象クラスでmakeSound()メソッドを定義し、具象クラスで実際の鳴き声を定義する必要があります。
PHPのオブジェクト指向

また、抽象クラスは、インターフェースと似た役割を果たすことができます。インターフェースは、抽象メソッドのみを持つクラスであり、複数のインターフェースを実装することができます。一方、抽象クラスは、具象メソッドを持つことができ、単一の抽象クラスしか継承することができません。
PHPのオブジェクト指向

抽象クラスは、継承することによってコードの再利用性を高めることができます。具象クラスは、抽象クラスのすべてのプロパティやメソッドを継承するため、共通の機能を持つクラスを簡単に作成することができます。また、抽象クラスは、具象クラスの実装を規定することができるため、開発者が間違った実装を行うことを防ぐことができます。
PHPのオブジェクト指向

抽象クラスは、多くの具象クラスで共通する機能を抽出し、再利用可能なコードを作成することができます。また、抽象クラスは、具象クラスが必ず実装しなければならないメソッドを定義することができ、コードの信頼性や保守性を高めることができます。
PHPのオブジェクト指向

トレイト (Trait) は、PHP5.4から導入された機能のひとつで、クラスで利用できるメソッドを、クラス継承の代わりに、再利用できるようにするための仕組みです。トレイトは、複数のクラスで共通する処理を定義することができます。
PHPのオブジェクト指向

トレイトを定義するには、 trait キーワードを使います。トレイトを実装するクラスは、 use キーワードを使ってトレイトを指定します。トレイトに定義されたメソッドは、 use されたクラスのインスタンスから呼び出すことができます。
PHPのオブジェクト指向

例えば、与えられた座標に移動する機能をもつ Point トレイトを定義しています。このトレイトには、コンストラクターで座標を設定する処理や、座標を文字列に変換する処理が含まれています。これらの処理は、 use するクラスで再利用することができます。
PHPのオブジェクト指向

トレイトを利用することで、コードの再利用性を向上させることができます。しかし、トレイトを多用しすぎると、コードが複雑になり、メンテナンスが困難になる場合があるため、注意が必要です。
PHPのオブジェクト指向

このコードは、トレイトを使用してクラスを構築する方法を示しています。
PHPのオブジェクト指向

Point トレイトは、2つのプロパティ $x と $y を持つ __construct コンストラクターと、__toString マジックメソッド、および moveTo メソッドを定義しています。このトレイトは、他のクラスに追加することができ、そのクラスに Point の機能を提供することができます。
PHPのオブジェクト指向

この例では、MyPoint クラスが定義され、Point トレイトが使用されています。MyPoint クラスには、自分で追加したメソッドやプロパティがなく、Point トレイトが提供するメソッドやプロパティを使用することができます。
PHPのオブジェクト指向

最後に、MyPoint クラスのインスタンス $point が作成され、初期化子によって x と y の値が設定されます。次に、__toString メソッドが呼び出され、(1, 2) という文字列が表示されます。moveTo メソッドが呼び出され、x と y の値が変更されます。最後に、再度 __toString メソッドが呼び出され、(3, 5) という文字列が表示されます。
PHPのオブジェクト指向

インターフェイスは、クラスがどのようなメソッドを提供する必要があるかを規定するために使用されるコードの抽象化です。 インターフェイスは実装を持ちませんが、そのメソッドの名前、引数の型、戻り値の型などを指定します。
PHPのオブジェクト指向

インターフェイスは、クラスの柔軟性を高めるために使用されます。複数のインターフェイスを実装することで、複数の機能を提供できます。また、複数のクラスが同じインターフェイスを実装することで、コードを共通化することができます。
PHPのオブジェクト指向

このコードは、Areableというインターフェイスを定義しています。インターフェイスは、クラスやトレイトが実装しなければならないメソッドを定義するためのものです。
PHPのオブジェクト指向

Areableインターフェイスは、area()というメソッドを持っています。このメソッドは、戻り値がfloat型であることを示しています。具体的には、面積を計算してその値を返すことが期待されています。
PHPのオブジェクト指向

例えば、正方形や円など、面積を計算する必要がある様々な図形がある場合、それらの図形を表すクラスを定義するときに、Areableインターフェイスを実装することで、各図形に対してarea()メソッドを提供することができます。
PHPのオブジェクト指向

前二節で解説したトレイトとインターフェースを参照したクラス定義の例です。
PHPのオブジェクト指向

このコードは、 Shape クラスが Areable インターフェースを実装し、 Point トレイトを使用していることを示しています。
PHPのオブジェクト指向

Shape クラスのコンストラクターは、 Point トレイトで定義されたコンストラクターをオーバーライドしています。それにより、 Shape クラスが Point トレイトを使用しているときに、 Shape クラスのコンストラクターが呼び出されるようになります。
PHPのオブジェクト指向

また、Shape クラスは __toString() メソッドを定義しており、これは Point トレイトで定義された同じメソッドをオーバーライドしています。これにより、 Shape オブジェクトを文字列として表現する際には、Point トレイトで定義された __toString() メソッドではなく、Shape クラスで定義された __toString() メソッドが呼び出されます。
PHPのオブジェクト指向

注目したいのは、use文の中でPoint::__constructとPoint::__toStringを別名として宣言しています。 これによって、Shapeクラスが自身で実装した__constructと__toStringメソッドを持つことができます。 __constructメソッドでは、親トレイトの__constructを呼び出しています。 __toStringメソッドでは、親トレイトの__toStringを呼び出して、点の座標を文字列として返します。
PHPのオブジェクト指向

最後に、 $shape オブジェクトを文字列として出力すると、 Shape クラスで定義された __toString() メソッドが呼び出され、 $shape --> (1, 2) という文字列が出力されます。
PHPのオブジェクト指向

Enumをクラスと一緒に解説するのは奇異に感じられるかもしれませんが、言語処理系としては、Enumはclassのインフラを使って実装しているので、メソッドやメソッドのアクセス記述子などの働きは同じです。
PHPのオブジェクト指向

このコードは、列挙型 (enum) Seasons を定義しています。
PHPのオブジェクト指向

Seasons は4つの要素 Spring、Summer、Autumn、Winter を定義しています。この列挙型の各要素に対して、kanji メソッドが定義されています。kanji メソッドは、match 式を使用して、要素に対応する漢字名を返します。
PHPのオブジェクト指向

もし match 式で、Seasons の列挙子を網羅していないと、 UnhandledMatchError がスローされます。これにより網羅性が担保されます。
PHPのオブジェクト指向

このコードの最後では、Seasons 列挙型のすべての要素に対して、要素名と kanji メソッドの結果を出力しています。それぞれの要素名と漢字名の組み合わせが出力されます。
PHPのオブジェクト指向

今節で取り上げた case に値を与えない Enum を Pure Enum といいます。 Pure Enum は UnitEnum interface の Implement です。
PHPのオブジェクト指向

前節で紹介したEnumのように case が特定のスカラー値と結びついていない Enum を Pure Enum といいます。 これに対して、これから紹介する case にスカラー型とスカラー値を明示した Enum を Backed Enum といいます。
PHPのオブジェクト指向

スカラー型を int と明示 この例では、W3C16 の値は int であり、明示的に int を指定しています。しかし、Enum では int 以外にも string が有効です。
PHPのオブジェクト指向

異なる case に同じ値を割り当てることはできません(エラーになります)。 Enum では、異なる case に同じ値を割り当てることはできません。そのため、コード中で同じ値が割り当てられている case がある場合には、エラーが発生します。
PHPのオブジェクト指向

Pure Enum の name に加え value もプロパティに持ちます。 Backed Enum では、各 case は value というプロパティを持ちます。このプロパティは、case の値を返します。また、name というプロパティも持ちます。
PHPのオブジェクト指向

クラスメソッド from() は値から case を引きます。 Enum には、クラスメソッド from() があります。このメソッドを使うと、指定された値に対応する case を取得できます。ただし、無効な値を指定すると ValueError が発生します。
PHPのオブジェクト指向

クラスメソッド tryFrom() は値から case を引きます。 Enum には、クラスメソッド tryFrom() もあります。このメソッドは、指定された値に対応する case を取得します。無効な値を指定すると、NULL が返されます。
PHPのオブジェクト指向

Enum は、機能的には連想配列に似ていますが、Backed Enum では、各 case は一意であり、value も一意であることが保証されています。これにより、プログラマーは、例外処理などの面倒を省くことができます。一方、連想配列はキーが重複しないことが保証されますが、value が重複することがあるため、プログラマーが例外処理を実装する必要があります。
PHPのオブジェクト指向

Backed Enum は BackedEnum interface の Implement です。
コードキャラリー

まとまった規模で、実用的な目的に叶うコードを読まないと機能の存在理由などの言語設計に思い至りにくいので、コードの断片から少し踏み込んだプログラムを掲載します。
コードキャラリー

PHPには複素数がないので、クラスとして実装しました。 ただ、8.1.13 の時点ではまだ演算子オーバーロードはないので、$x->add($y) のようにメソッドで実装しました。
コードキャラリー

このPHPスクリプトは、複素数を表現するComplexクラスを定義しています。複素数は、実数部分と虚数部分を持ちます。
コードキャラリー

Complexクラスのコンストラクタは、実数部分と虚数部分を初期化します。コンストラクタの引数には、float型のプロパティ$realと$imaginaryがあります。各プロパティは、引数のデフォルト値が0に設定されています。
コードキャラリー

__toString()メソッドは、Complexオブジェクトを文字列に変換するために使用されます。虚数部分が0の場合は、実数部分のみが表示されます。実数部分が0の場合は、虚数部分と文字"i"が表示されます。虚数部分が負数の場合は、負数を括弧で囲みます。それ以外の場合は、実数部分と虚数部分が+記号で連結され、文字"i"が追加されます。
コードキャラリー

coerce()メソッドは、$right引数をComplexオブジェクトに変換します。gettype()関数を使用して、$rightの型を確認します。integerまたはdoubleの場合、新しいComplexオブジェクトが作成され、$rightの値が実数部分に設定されます。objectの場合、get_class()関数を使用して、$rightがComplexオブジェクトであることを確認します。それ以外の場合、coerce()メソッドは例外をスローします。
コードキャラリー

add()メソッドとsub()メソッドは、複素数の加算と減算を行います。coerce()メソッドを使用して、引数をComplexオブジェクトに変換します。新しいComplexオブジェクトが作成され、$thisオブジェクトと$rightオブジェクトの実数部分と虚数部分が加算または減算されます。
コードキャラリー

abs()メソッドは、Complexオブジェクトの絶対値を計算します。絶対値は、複素数の実数部分の2乗と虚数部分の2乗の平方根です。
コードキャラリー

最後に、スクリプトは、Complexオブジェクトの作成と演算を実行して、結果を出力します。例えば、"$x + $y --> {$x->add($y)}"という行は、Complexオブジェクト$xと$yを加算し、結果を表示します。
コードキャラリー

図形クラス(Shape)から正方形(Square)や楕円形(Oval)などを派生しています。 Shape自身は、interface Areable の実装で、Areableは共通するメソッド area()を定義しており、area() を実装しないとShapeから派生できません。
コードキャラリー

このPHPコードは、幾何学的な形状(正方形、長方形、円、楕円)を表すために、トレイト(trait)を使用したオブジェクト指向プログラミングの例を示しています。
コードキャラリー

まず、Pointというトレイトを定義しています。このトレイトは、x座標とy座標を表すプロパティと、座標を移動するmoveToメソッドを持っています。
コードキャラリー

次に、Areableというインターフェイスを定義しています。このインターフェイスには、面積を返すareaメソッドが含まれています。
コードキャラリー

そして、Shapeクラスを定義しています。このクラスは、Pointトレイトを使用して、x座標とy座標を持っています。また、Areableインターフェイスを実装しており、areaメソッドをオーバーライドして0を返すようにしています。このクラスは、正方形、長方形、円、楕円の基底クラスとして使用されます。
コードキャラリー

Square、Rectangle、Circle、Ovalクラスは、Shapeクラスを拡張しています。それぞれが異なるプロパティを持っており、それぞれが面積を計算するためにareaメソッドをオーバーライドしています。
コードキャラリー

最後に、いくつかの形状のインスタンスを作成し、それらの面積を計算して表示するためのコードがあります。また、PointトレイトのmoveToメソッドを使用して、Ovalの座標を変更しています。
コードキャラリー

このプログラムは、オブジェクト指向プログラミングの基本的な概念を示しています。特に、クラスの継承、トレイトの使用、インターフェイスの実装などが重要な要素です。また、オブジェクトの状態を変更するメソッド(moveTo)を定義しています。