クラス
概要
クラスとは変数と関数を持つことができるデータ構造のことで、 処理を機能単位で分割することができます。
型
クラスは「オブジェクト型」として扱われます。
定義
クラスは定義することで変数や関数を持つことができます。 ※クラス内に宣言する変数を「メンバ変数」、 クラス内に宣言する関数を「メソッド」、 メンバ変数、メソッド、両方をあわせて「メンバ」と呼びます。
書式
クラスの定義は以下のように書きます。
class クラス名
{
アクセス指定子 メンバ変数名;
アクセス指定子 メソッド
}
具体例
以下のコードはクラス「TestClass」を定義しています。
このクラスが持っているメンバはメンバ変数が「$m_Val」、
メソッドは「PrintInfo」です。
※アクセス指定子については後ほど説明します。
class TestClass
{
public $m_Val;
public function PrintInfo()
{
echo "TestClass";
}
}
クラスの使用
定義したクラスは変数として使用することが可能です。 ただし、通常の変数と違って作成時に「new」キーワードを使用しないといけません。
new
クラスを作成するために使用するキーワードです。 このキーワードを使用しないとクラスは作れません。
書式
※以下の例は上記のTestClassを宣言している前提とします。
書式 | 例 |
---|---|
$変数名 = new クラス名(コンストラクタ引数); | $test = new TestClass(); |
メンバの使用方法
オブジェクトをインスタンス化できたら、そのインスタンスの
メンバを使用することができるようになります。
メンバの使用は変数名とメンバメンバの間に「->」を
挿入することで可能です。
※「->」は「アロー演算子」と呼ばれています。
// TestClassのPrintInfoメソッドを呼び出す。
$test->PrintInfo();
メソッドでのメンバ変数の注意
メソッド内ではメンバ変数を自由に使用することができますが 使用するには「this」をメンバ変数の前につける必要があります。 このthisはクラス自身を指しており、thisをつけることは 「自分のメンバの~」という意味になります。
付けた例
class Robot
{
private $m_Name = "robot";
public function PrintInfo()
{
echo $this->m_Name;
}
}
$robot = new Robot();
$robot->PrintInfo();
出力結果
付けなかった例
class Robot
{
private $m_Name = "robot";
public function PrintInfo()
{
echo $m_Name;
}
}
$robot = new Robot();
$robot->PrintInfo();
出力結果
上の結果のようにつけないとメンバとして認識されず、 エラー($m_Nameが定義されていません)として扱われます。
アクセス指定子
アクセス指定子とはメンバのアクセス権限用キーワードのことです。 「public」「private」「protected」があり、 一つ一つに有効範囲が定められています。 指定方法は共通しており、各メンバの先頭にアクセス指定子をつけます。
public
publicをつけたメンバはクラスの内外から自由にアクセス可能となります。
例
以下の例のようにpublicをつけた「m_Name」と「ChangeName」は
クラス内でもクラスの外からでも使用できています。
class PublicTest
{
public $m_Name;
public function ChangeName($change_name)
{
$this->m_Name = $change_name;
}
}
$public_test = new PublicTest();
$public_test->m_Name = "abc";
echo "$public_test->m_Name<br>";
$public_test->ChangeName("def");
echo "$public_test->m_Name<br>";
出力結果
private
privateをつけたメンバはクラス内からしかアクセスできません。 クラスの外からアクセスしようとするとエラーになります。
エラー例
class PrivateTest
{
private $m_Name;
public function ChangeName($change_name)
{
$this->m_Name = $change_name;
}
}
$private_test = new PrivateTest();
$private_test->m_Name = "abc";
echo "$private_test->m_Name<br>";
$private_test->ChangeName("def");
echo "$private_test->m_Name<br>";
出力結果
「Cannot access private」とあるようにprivateのm_Nameには アクセスできないという意図のメッセージです。
問題がない使用例
class PrivateTest
{
private $m_Name;
public function ChangeName($change_name)
{
$this->m_Name = $change_name;
}
public function PrintName()
{
echo "$this->m_Name<br>";
}
}
$private_test = new PrivateTest();
$private_test->ChangeName("def");
$private_test->PrintName();
出力結果
上記の実行結果はm_Nameは「ChangeName」メソッド、 「PrintName」メソッドで使用しており、クラスの外では使用していません。 このようにprivateのメンバはクラス内でのアクセスには何も問題ありません。
protected
protectedはprivateと同じくクラス内でしかアクセスできません。 ただ、privateとは違い継承と呼ばれる機能を使って作成した クラスでも使用できます。 ※継承、protectedについては別で詳しく記述します。
アクセス指定子の意味
クラスの中のメンバは全て外に公開する必要はありません。 公開するということは、そのメンバを自由に参照、変更できるということです。 それは、ソースの保守性を著しく低下させます。 誰でも変更できるということは、どこからでもバグが発生するということと 同じ意味と考えても問題ありません。 そのようなことにならないように、公開していいメンバと公開してはいけない メンバを分けるためにアクセス指定子は存在しています。
コンストラクタ、デストラクタ
クラスにはコンストラクタとデストラクタという特殊なメソッドがあります。
コンストラクタ
コンストラクタはクラスがインスタンス化された際に呼び出されるメソッドで、 主にメンバの初期化を行うために使用します。
書式
コンストラクタはメソッド名が決まっており、「__construct」以外は使えません。
function __construct()
{
}
具体例
class ConstructTest
{
function __construct()
{
echo "Boost Construct";
}
}
$const_test = new ConstructTest();
出力結果
デストラクタ
デストラクタはインスタンスが破棄される際に呼び出されるメソッドです。 終了時に行う処理なので、ファイルなどのリソースが開かれたままに なっていないかなどの最終チェックを行うときに使用されます。
書式
デストラクタもコンストラクタ同様にメソッド名が決まっており、
「__destruct」以外は使えません。
function __destruct()
{
}
具体例
class DestructTest
{
function __destruct()
{
echo "Boost Destruct<br>";
}
}
$dest_test = new DestructTest();
$dest_test = null;
echo "end";
出力結果
タイミング
デストラクタが呼び出されるタイミングは参照が0になった後か、 プログラムが終了する瞬間です。
例
class DestructTest
{
function __destruct()
{
echo "Boost Destruct<br>";
}
}
$dest_test = new DestructTest();
$dest_test2 = $dest_test;
$dest_test = null;
echo "Test<br>";
$dest_test2 = null;
echo "end";
出力結果
参照カウンタ
上記のコードでは「Test => Boot Destruct => end」の順番で出力されています。 これはオブジェクト型は「参照カウンタ」という数値を持っているためです。 参照カウンタはオブジェクト型を格納している変数の数を指しており、 デストラクタはこの値が0になった際に初めて実行されます。 ですので、上記のコードではdest_testとdest_test2の 2箇所でインスタンス化したDestructTestを保持しているので、 dest_testにnullを代入しただけでは参照カウンタが 1減るだけなので、デストラクタは呼ばれません。dest_test = null; // 参照カウンタ - 1
デストラクタが呼ばれるのはdest_test2をnullして参照カウンタを0にした瞬間です。dest_test2 = null; // 参照カウンタ - 1
このようにデストラクタが呼ばれるタイミングは参照カウンタを意識して実行しないと 最後まで呼ばれない可能性がありますので、注意が必要です。