こんにちは、大学院でIT系の研究を専攻している、ひらりんです。
PHPはサーバーサイドで動く言語で、世界中の多くのWebサイトがPHPによって記述されています。一括してコンパイルするのではなく、実行時に一行ずつコンパイルされることから、随時コードを確認でき、初心者も取り組みやすい言語のひとつとされています。
PHPのクラスの一つに、abstractクラスがあります。簡単に説明すると、クラスを抽象化をしたものですが、その特徴や文法、定義の方法の理解は難しいですよね。本記事では、PHPのabstractについて、クラスの違いや定義方法などを、分かりやすくご紹介します。あらかじめ、PHPの基礎であるプロパティやコンストラクター、インスタンスやアクセス修飾子などについて分かっていると、より理解が深まります!
PHP初心者や、これからPHPを用いて動的なWebページを作ろうと思っている方は、ぜひ読んでみてください。
目次
PHPのabstractクラスとは
PHPは、定義内の関数である「メソッド」の実装には、abstractとinterfaceの2つが用いられます。abstractは日本語にすると、「抽象的な」となり、interfaceは「接点」という意味です。
今回のテーマのabstractクラスは、サブクラスにて、実装することを義務付ける抽象メソッドを定義できます。ちなみに、サブクラスとはクラスを継承する子クラスのことです。つまり、他クラスでの継承を前提としており、抽象メソッドを1つ以上持っています。一方で、直接インスタンスを生成することはできずに、データなどを引き継がなければ実行されません。
PHPのabstractの使い方
PHPのabstractについて、実際にプログラムを用いながら説明します。
abstractが実装面で、interfaceと決定的に違う点は、「部分的な実装」ができるということです。どのようなことなのかを解説します。PHPのabstractクラスの宣言は、次のように記述されます。
1 2 3 4 5 6 7 |
abstract class クラス名 { abstract アクセス修飾子 function メソッド名(); // 抽象メソッド アクセス修飾子 function メソッド名() { } } |
abstractクラスは、classの前に「abstract」と記述するだけで、クラスを定義できます。どこからアクセスするか指定する、アクセス修飾子については、「public」と「protected」は使用できますが、「private」は用いられません。メソッドについても、アクセス修飾子の前に、クラスと同様に「abstract」と書けば、抽象メソッドを定義することができます。
abstractクラスの継承については、PHPの他のクラスと同様、以下のように「extends」演算子を使用します。abstractクラスを継承したサブクラスは、abstractクラス内で「abstract」宣言されたメソッドについては、すべて実装する必要がある点に注意してください。
1 2 3 4 |
class クラス名 extends 抽象クラス { // 抽象クラスで定義していたメソッド } |
なお、abstractクラスは、クラスのひとつであるため、抽象メソッドだけでなく、一般的なメソッドやプロパティも定義できますが、「抽象プロパティ」は定義できません。エラー頻出事項なので、気を付けましょう。
PHPのabstractの特徴は?
では、どのような場面でabstractを用いることが有効なのでしょうか?abstractとinterfaceを比較しながら解説します。
abstractは、継承することが主たる目的です。他の言語のいわゆる「クラス」と本質的には同様で、あらかじめ実装できるものは実装することに適しています。後の処理の中で、複数の派生先の中で一部異なる処理がある場合に効果的で、実装の継承が可能となります。
一方で、interfaceは、保証することが本質的な特徴です。厳密にいうと、interfaceは「クラス」ではなく、実装を伴うメソッドやプロパティは定義できません。言い換えると、型のみを定義できるのが特徴です。さらに、interfaceで定義したメソッドについては、クラスの中ですべて使用する必要があります。
言葉だけで説明しても、PHP初学者やプログラミングを始めたばかりの人は難しいですよね。次の章では実際にプログラムを用いながら分かりやすく説明します。abstractとinterfaceそれぞれの違いを確認してみましょう!
PHPのabstractの活用法
実際に、PHPのabstractを中心に、interfaceのプログラムと比較しながらプログラム例を見ていきましょう。ここでは、人(Human)、犬(Dog)、ロボット(Robot)の3つのクラスが、後に定義されるとします。それぞれの記述法の機能に合わせて、クラス内での役割を説明します。
interfaceのプログラム実装例
まずはじめに、interfaceについて簡単に見てみましょう。ここでは、人と犬とロボットを繋ぐコミュニケーションツールとして、Conversationインターフェイスを宣言し、「talk」というメソッドを定義しています。
1 2 3 4 |
interface Conversation { public function talk(); } |
interfaceはimplements演算子によって、サブクラスに実装され、interfaceで宣言されたメソッドすべて実装する必要があります。言い換えると、「talk」を実装する予定のないクラスには、Conversationインターフェイスを継承してはいけないということになります。
abstractのプログラム実装例
続いて、abstractについてです。まずはプログラムを見てみましょう。
1 2 3 4 5 6 7 8 |
abstract class Active { abstract public function eat(); public function Speak() { // おなかすいた } } |
abstractクラスの「Active」の中で、抽象メソッドの「eat」と、通常のメソッドの「Speak」を定義しています。このように、abstractクラスでは、抽象メソッドと通常のメソッドを同時に定義することができます。
では、各宣言やクラスを継承している3つのクラスの人(Human)、犬(Dog)、ロボット(Robot)を通して、継承の方法などを確認してみましょう。
abstractとinterfaceの継承プログラムの実装例
abstractクラスについてはextends演算子、interfaceについてはimplements演算子を用いて、それぞれ人(Human)、犬(Dog)、ロボット(Robot)のサブクラスに継承します。
Robotクラスについては、Conversationインターフェイスの「talk」のみを宣言します。talkの内容はロボット用に実装をしています。
1 2 3 4 5 6 7 |
class Robot implements Conversation { public function talk() { echo 'ウィーン(ロボット音)'; } } |
続いて、Dogクラスについては、Conversationインターフェイスの「talk」とabstractの「Active」クラスより「eat」を宣言します。抽象メソッドについては必ず宣言する必要がありますが、犬は話せないので「speak」はここでは宣言していません。
1 2 3 4 5 6 7 8 9 10 11 |
class Dog extends Active implements Conversation { public function talk() { echo 'ワン!'; } public function eat() { echo 'ドッグフード'; } } |
Humanクラスについては、すべて宣言しています。犬クラスで継承したメソッドに加えて、通常のメソッドの「speak」についても継承しています。
1 2 3 4 5 6 7 8 9 10 11 12 |
class Human extends Active implements Conversation { public function talk() { echo 'ハロー'; } public function eat() { echo 'ご飯'; } public function speak(); } |
このように、abstractとinterefaceは類似している機能を持っていますが、演算子の使い分けによって、プログラムの簡略化などに活かせそうですね!
まとめ
いかがでしたでしょうか?今回は、PHPのabstractについて説明しました。
PHPは、便利なフレームワークが多く、初心者でも学習しやすい言語ですが、abstractとinterfaceのクラスの違いや利点を理解すると、さらに汎用性が広がります。
ぜひ、PHPのabstractを学習し、Webサービス作成やシステム構築に活かしてください。