PHPプログラミング

入門

第14章 クラス

この章では、前章「第13章 オブジェクト指向」で見てきたベースとなるオブジェクトを、実際にコードで表現していきます。

目次

ベースとなるオブジェクト

前章同様、ECサイトで取り扱う商品をオブジェクトにしていきます。
全ての商品に共通して必要となりそうな要素は次の4つでした。

  • 商品ジャンル
  • 商品名
  • 値段
  • 商品説明

そして、これらのプロパティから値を取得するためのメソッドは次の4つです。

  • getGenre・・・商品ジャンルを取得するメソッド
  • getName・・・商品名を取得するメソッド
  • getPrice・・・値段を取得するメソッド
  • getDescription・・・商品説明を取得するメソッド

取得するget系メソッドに加えて、プロパティに値を設定するset系メソッドも用意しましょう。

  • setGenre・・・商品ジャンルのプロパティに値をセットする
  • setName・・・商品名のプロパティに値をセットする
  • setPrice・・・値段のプロパティに値をセットする
  • setDescription・・・商品説明のプロパティに値をセットする

オブジェクトの定義

必要なプロパティとメソッドが揃ったところで、いよいよオブジェクトの定義をしていきましょう。
定義にはclass(クラス)を使います。
ベースオブジェクト用のファイルを作成していきますが、オブジェクトを定義するファイルは専用のフォルダを作成し、その中へ入れるようにすると管理が簡単になります。
ここでは「class」フォルダを作成し、その中に「Item.php」を作りました。
次のコードを入力してください。

class/Item.php

<?php
class Item {
}

次に4つのプロパティを宣言します。

class/Item.php(修正)

<?php
class Item {
	private $genre;
	private $name;
	private $price;
	private $description;
}

class Item{}に囲まれているだけで、変数の宣言と変わりませんね。
変数の前に付いているprivateが気になるかもしれませんが、ここでは一旦飛ばしてください。全てのメソッドを追加した後に解説します。

続いて、get系メソッドを宣言します。次のコードを追記してください。

class/Item.php(修正)

<?php
class Item {
	プロパティ

	public function getGenre()
	{
		return $this->genre;
	}

	public function getName()
	{
		return $this->name;
	}

	public function getPrice()
	{
		return $this->price;
	}

	public function getDescription()
	{
		return $this->description;
	}
}

プロパティ宣言時のprivateと同様、メソッドの宣言でもpublicという意味不明なものが付いています。こちらも合わせて、後ほど解説します。

値を返すだけなので単純にreturn $genre;になるかと思いきや、変数の前に$this->という見慣れないものが付いています。この「$this」は、オブジェクト内のプロパティを参照するときに使う「プレフィックス」と呼ばれるものです。「this」を訳すと「これ」「この」といった意味になりますが、ここでは「このオブジェクト内の」という意味になります。

したがって、$this->genreは「このオブジェクト内の$genre」になります。
$this->プレフィックスを使う際は、変数の頭に付ける「$」の位置が「this」の前に来ればOKです。
「$this->$genre」のように「$」を2つ書く必要はありません。

get系メソッドに続いて、set系メソッドを宣言していきます。

class/Item.php(修正)

<?php
class Item {
	プロパティ

	get系メソッド

	public function setGenre($genre=null)
	{
		$this->genre = $genre;
	}

	public function setName($name=null)
	{
		$this->name = $name;
	}

	public function setPrice($price=null)
	{
		$this->price = $price;
	}

	public function setDescription($description=null)
	{
		$this->description = $description;
	}
}

setGenreメソッドの動きを見てみましょう。
$genreで引数を受け取って、プロパティの$genreへ値を代入しています。

少し紛らわしいかもしれませんが、引数を受け取る$genreとプロパティの$genreは別の変数です。ここは大事なところなので、もう少し詳しく解説していきます。

変数の使用範囲を決めるスコープ

引数を受け取る$genreは、宣言されたsetGenreメソッド内でのみ使うことができます。
なので、getGenreメソッドやsetNameメソッドなどの別メソッド内で同じ変数$genreを使おうとしても、存在しない変数と判断されエラーが出てしまいます。

一方で「$this->」プレフィックスが付いた$genreは、class内ならどこからでも使うことができます。getGenreメソッドやsetGenreメソッド以外からでも、もちろん大丈夫です。
しかし、クラスの外からItemクラス内の$genreを使用することはできません。

このように、変数には使用できる範囲が決められています。この範囲のことを「スコープ」と呼びます。

変数のスコープは宣言された場所や、プロパティの宣言で使った「private」などのスコープエンティティで決定されます。次に、スコープエンティティについて見ていきましょう。

スコープエンティティ

スコープエンティティはpublicprotectedprivateの3種類があります。それぞれをプロパティやメソッドの宣言時に指定することで、どの範囲で使用できるかを明示的に決めることができます。

public

publicはスコープの範囲が最も広く、クラスの外からでもアクセスできることを宣言します。
Itemクラスのメソッド宣言時に指定していますが、これはクラスの外からでも自由にメソッドを呼び出せるようにするためです。
ちなみに、スコープエンティティを指定しなかった場合もpublicの指定になります。

他の人がコードを読むことなどのメンテナンス性を考え、できるだけ明示しておく方が親切です。

protected

protectedは2番目に広い範囲のスコープを持ちます。このエンティティはクラス内と、そのクラスの親クラス、もしくは継承した子クラスからアクセスすることができます。「継承」を使っている場合には特に有効なスコープです。

private

privateは最も範囲が限られたスコープです。このエンティティを指定したプロパティ、メソッドは宣言されたクラス内からしかアクセスすることができません。この後に解説する「カプセル化」を使う際に活躍します。

オブジェクトのカプセル化

クラス内で宣言したプロパティの値が、クラス外からも自由に書き換えることができると、意図しないタイミングで値を変更してしまう可能性があります。そのようなことが起こらないように、プロパティを守る仕組みを「カプセル化」と呼びます。

仕組みと実装方法はシンプルです。
クラス内のプロパティをprivateスコープエンティティで宣言します。これでクラス外からはプロパティにアクセスできなくなりました。
次に、このプロパティにアクセスするためのメソッドをpublicスコープエンティティで指定して宣言します。メソッドからは同じクラス内のプロパティへアクセスすることができます。したがって、クラス外からクラス内のプロパティへアクセスするには、このメソッドを呼び出すしかなくなります。

こうすることで、プロパティをクラス外からの直接的なアクセスから守ることができるようになりました。
上記のプロパティにアクセスするためのメソッドを「アクセッサメソッド」と呼びます。

実は、先ほど作成したItemクラスはカプセル化された構造になっています。

図1:Itemクラスのカプセル化イメージ

Itemクラスのカプセル化イメージ

Itemクラス内のプロパティは全てprivateスコープエンティティを指定しています。
なので、クラス外からは直接プロパティへアクセスして値を取得したり、変更することができません。
そこで必要となるのが、プロパティへアクセスするためのアクセッサメソッドです。get系メソッドはプロパティの値を取得するために使い、set系メソッドはプロパティの値を設定(変更)するために使います。

まとめ

ここまでで、クラスを定義してベースとなるオブジェクトを作りました。次章ではこのオブジェクトを基に、色々な商品のオブジェクトを作っていきましょう。

この章で学んだこと

  • オブジェクトの定義にはclassを使う
  • プロパティ、メソッドは「スコープエンティティ」(publicprotectedprivate)を指定して宣言する
  • オブジェクトのカプセル化を使い、プロパティの値は「アクセッサメソッド」からのみアクセスできるようにする

こちらの記事は役に立ちましたか?

ありがとうございます。
もしよろしければ、あわせてフィードバックや要望などをご入力ください。

ありがとうございます。
コメントを送信しました。