継承の最後に、新しいアクセス修飾子を紹介します。アクセス修飾子は連載第14回でpublicとprivateがあることを紹介しました。実は、もう1つ「protected」というのがあります。
早速、「protectedが、どのような働きをするのか」についてサンプルを作りながら見ていきましょう。ここでは、連載第15回のリスト3のCircleクラスを使います。
まず、phplesson/chap15/Circle.phpをファイルごとchap17フォルダ内にコピーしてください。次に、このCircleクラスを継承した以下のSphereクラスを作成してください。
<?php class Sphere extends Circle { //球の表面積を計算するメソッド public function getSurfaceArea(): float { return 4 * self::PI * $this->radius * $this->radius; // (1) } }
コメントにあるように、プロパティの半径と定数の円周率を使って球の表面積を計算するメソッドが1つだけです。このSphereクラスを利用する以下のuseSphere.phpを作成し、実行してください。
<?php require_once("Circle.php"); require_once("Sphere.php"); $sphere = new Sphere(5); // (1) $surface = $sphere->getSurfaceArea(); print("球の表面積: ".$surface);
実行結果は、以下のようにエラーとなります。
Notice: Undefined property: Sphere::$radius in C:\xampp\htdocs\phplesson\chap17\Sphere.php on line 7 Notice: Undefined property: Sphere::$radius in C:\xampp\htdocs\phplesson\chap17\Sphere.php on line 7 球の表面積: 0
エラーの原因は、エラーメッセージにもあるようにリスト9の(1)で存在しない$radiusプロパティにアクセスしていることです。確かに、$radiusプロパティは親クラスであるCircleクラスには記述されていますが、privateプロパティとなっています。privateプロパティは自クラス内でのみアクセス可能なので、子クラスからはアクセスできません(図3)。privateのこの性質はメソッドに対しても当てはまります。
この問題を解決するために、$radiusプロパティをpublicにするという考え方もありますが、それではカプセル化が実現できません。そこで新しいアクセス修飾子である「protected」を導入します。
Circleクラスの7行目を下記リスト11のように書き換えて、再度useSphere.phpを実行してください。
<?php class Circle { //πを表す定数 const PI = 3.14; //半径を表すプロパティ protected $radius = 0; 〜省略〜 }
実行結果は以下の通りです。
球の表面積: 314
今度はエラーにならずに済みました。
protectedは自クラスと子クラスからのみアクセス可能なメンバを表します(図4)。
一方、publicとは違い、外部のクラスや実行phpからアクセスすることはできません。もしuseSphere.phpに以下のコードを記述し、実行すると、「Fatal error: Uncaught Error: Cannot access protected property Sphere::$radius」と、エラーになります。
$sphere->radius;
そのため、カプセル化は保たれています。
次回は、オブジェクト指向の3大特徴の1つであるポリモーフィズムを実現する方法である抽象クラスとインタフェースを扱います。
Copyright © ITmedia, Inc. All Rights Reserved.