クラスの練習問題2
- 2013 8/9
下記の問題を練習サイトに記述をしてください。
その1
アクセス修飾子の簡単な説明
その2
アクセサメソッドを介してメンバ変数(プロパティ)にアクセスするメリットは何でしょうか?
カテゴリー : 2013年 8月
下記の問題を練習サイトに記述をしてください。
その1
アクセス修飾子の簡単な説明
その2
アクセサメソッドを介してメンバ変数(プロパティ)にアクセスするメリットは何でしょうか?
継承とは簡単にいうと継承とは、既に存在するあるクラスを元に、それを更に拡張したクラスを作る仕組みです。
継承元となるクラスはスーパークラス。継承の結果できたクラスをサブクラスと言います。
具体例として先ほど作成したPersonクラスと似たようなクラスBusinessPersonを作ってみます。
1 2 3 4 5 6 7 8 9 |
require_once dirname(__FILE__).'/Person.php'; class BusinessPerson extends Person{ //サブクラス独自のworkメソッドを定義 public function work(){ echo "<p>{$this -> lastName}{$this -> firstName}は働いています。</p>"; } } |
*require_once dirname(__FILE__).’/Person.php’のdirname(__FILE__)でファイルの絶対パスを通して、インクルードの動作を確実にしています。
実行コードで
1 2 3 4 5 |
require_once "./classes/BusinessPerson.php"; $bp = new BusinessPerson('名無し','ごんべい'); $bp -> work(); $bp -> show(); |
このようにして見ましょう。
インスタンスを行っているのは、BusinessPersonクラスのみです。しかし、Pesonクラスのメソッドshow()にもアクセスが可能ですね。サブクラスからはスーパークラスのあれやこれやが参照できるのです。
順番としては、インスタンス化されたクラスの参照先を探し、なければ継承元(スーパークラス)に参照を求めるという動きです。
ちなみに、PHPでは多重継承はみとめていません。
スーパークラスで定義したメソッドをサブクラスで上書きすることをオーバーライドと言います。
実際に行ってみましょう。
下記のようにBusinessPersonクラスを継承したEliteBusinessPersonクラスを作成してください。
1 2 3 4 5 6 7 8 |
require_once dirname(__FILE__)."/BusinessPerson.php"; class EliteBusinessPerson extends BusinessPerson{ public function work(){ echo "<p>{$this -> lastName}{$this -> firstName} はバリバリ働いています。</p>"; } } |
実行コードは下記のようにしてみましょう。
1 2 3 4 5 |
require_once "./classes/EliteBusinessPerson.php"; $bp = new EliteBusinessPerson('時','任三郎'); $bp -> work(); $bp -> show(); |
継承元のBusinessPersonクラスのwork()メソッドはEliteBusinessPersonクラスによって上書きされました。 しかしshow()メソッドは多段階さかのぼり大元のPerosnクラスの者を参照していることが確認できますね。
スーパークラスの機能を利用しつつ、サブクラス側で独自の機能を追加する場合などにしようしてみましょう。
HetareBusinessPersonクラスを作成します。
1 2 3 4 5 6 7 8 9 10 |
require_once dirname(__FILE__)."/BusinessPerson.php"; class HetareBusinessPerosn extends BusinessPerson{ //BusinessPerosnのwork()メソッドをオーバーライド public function work(){ parent :: work(); echo "ただしぼちぼちとねwww"; } } |
BusinessPersonクラスを継承をしています。且つ、BusinessPersonクラスのwork()メソッドをオーバーライドさせているのですが、スーパークラスのwork()メソッドも利用しています。その際にparentキーワードと :: 演算子で メソッドを結んでいます。
実行コードは
1 2 3 4 |
require_once "./classes/HetareBusinessPerson.php"; $hbp = new HetareBusinessPerosn('植木','ひとし'); $hbp -> work(); |
で確認をして見ましょう。
スーパークラスのコンストラクタを流用しながらサブクラスのスーパークラスを定義することもできます。
Foreignerクラスを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
require_once dirname(__FILE__)."/Person.php"; class Forigner extends Person{ //追加プロパティ public $middleName; //スーパークラスのコンストラクタをオーバーライド public function __construct($lastName,$middleName,$firstName){ //スーパークラスのコンストラクタを呼び出し parent :: __construct($firstName,$lastName); //middleNameの初期化 $this -> middleName = $middleName; } //showメソッドのオーバーライド public function show(){ echo "<p>僕の名前は、{$this -> firstName}.{$this -> middleName}.{$this -> lastName}です。</p>"; } } |
実行コードは、
1 2 3 4 |
require_once "./classes/Forigner.php"; $hbp = new Forigner('ヤマダ','ルイ','十三世'); $hbp -> show(); |
スーパークラスのコンストラクタを利用しつつ、コンストラクタをひとつ追加していますね。その際にparentキーワードと::演算子でスーパークラスのコンストラクタを呼び出しています。
各クラスでオーバーライドを禁止して、クラスの不用意な書き換えを予防するのが、final修飾子です。このアクセス修飾子をメソッドを public final function work(){ } のようにメソッドや、final class BusinessPerson{} のようにクラス全体に記述することによって、final修飾子のついた単位でオーバーライドを禁止することができます。
問題1 次の図は継承を説明したものです。 空欄を埋めなさい。
{ ① }
↑ { ② }キーワード
{ ③ }
問題2
次のようなMyClass があるものとします。 getDataメソッドを継承し、文字列全体を【 】で囲むように変更してみましょう。 尚継承に際しては、parentキーワードも利用するようにしましょう。
1 2 3 4 5 6 7 8 9 |
class MyClass{ protected $data; public function __construct($data){ $this -> data = $data; } public function getData(){ return $this -> data; } } |
日本語では多様性とかに訳されます。
もう少し具体的にいうと クラスは異なっても同じ名前のメソッドでいろんな動きを実現させる事です。
実際に行ってみます。
スーパークラス Figure コンストラクタのみをもったクラスです。
1 2 3 4 5 6 7 8 9 10 11 |
class Figure{ protected $width; protected $height; //コンストラクタ public function __construct($width,$height){ $this -> width = $width; $this -> height = $height; } } |
Figureクラスを継承したサブクラスTriangle 三角形の面積をメソッドgetAreaで計算するクラス
1 2 3 4 5 6 7 8 9 |
require_once dirname(__FILE__)."/Figure.php"; class Triangle extends Figure{ //三角形の面積 public function getArea(){ return $this -> width * $this -> height / 2; } } |
Figureクラスを継承したサブクラスSquer 四角形の面積をTriangleと同じくgetAreaで計算するクラス
1 2 3 4 5 6 7 8 |
require_once dirname(__FILE__)."/Figure.php"; class Squer extends Figure{ //四角形の面積 public function getArea(){ return $this -> width * $this -> height ; } } |
実行コード
1 2 3 4 5 6 7 |
require_once "./classes/Triangle.php"; require_once "./classes/Squer.php"; $tri = new Triangle(5,10); $squ = new Squer(5,10); echo "三角形の面積{$tri -> getArea()}<br>"; echo "四角形の面積{$squ -> getArea()}"; |
両方とも同じクラスFigureを継承し、かつgetAreaで処理を行っています。