メンバへのアクセス方法について

2.3 メンバへのアクセス方法について

 クラスを利用しオブジェクトを生成する方法について前節で学習してきました。しかしオブジェクトを生成しただけでは本当にクラスを最大限利用したことにはなりません。オブジェクトに定義されている「メンバ(フィールド変数やメソッド)」を利用してこそ本来の意味があります。では実際にメンバへのアクセス方法について学習していきましょう。

 凡例:オブジェクト内のフィールド変数とメソッドへのアクセス方法
 2.2.1項で定義した「Computer」クラスを例にしています。
 下記のように「Computer」オブジェクトを1つ生成すると、コンピュータ1台のメモリの設定や音を鳴らすといった、そのオブジェクトのフィールド変数やメソッドへのアクセスができるようになります。
 生成したオブジェクトは値が格納できる「$os、$cpu、$memory」などのフィールド変数(属性)と、「起動、終了、音を鳴らす」などが行えるメソッド(操作)を持ちます。値を設定したい場合は、このフィールド変数(属性)へ実際に値を代入し、何か動作をさせたければメソッド(操作)を利用すれば良いのです。

 「$com->os」と記述すれば、$comにあるComputerクラスのオブジェクト内に生成されたOSの変数を表すことができ、OSをWindowsXPにしたい場合は上記のように代入し、「com->start();」と記述すれば起動という操作が行えることになります。
 それでは、次の項にて実際にメンバへアクセスするサンプルを紹介します。

2.3.2 フィールド変数に値を設定するプログラム

 オブジェクトのフィールド変数へ値をダイレクトに設定し、その結果を画面に出力します。
フィールド変数へのアクセス方法について学習しましょう。

ソースコード

ソース・フォルダー  :myproj_framework_basic/ch02
ファイル名      :fieldVariable.php
アクセスURL    :http://localhost/myproj_framework_basic/ch02/fieldVariable.php

➢ fieldVariable.php

<?php
    // クラスの定義作成
    class Computer2{
        public $os;
        public $memory;
    }

    // Computer2クラスのオブジェクト生成
    $com = new Computer2();

    // メンバの呼び出し、代入
    $com->os = "WindowsXP";
    $com->memory = 2048;
?>
<html>
    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    	<title>フィールド変数に設定</title>
    </head>
    <body>
    	<?php
        	// オブジェクトのフィールド変数の値を参照し、結果を画面に表示する
        	echo "パソコンのOSは「" . $com->os . "」です。<br>";
        	echo "メモリサイズは「" . $com->memory . "MByte」です。";
    	?>
    </body>
</html>
	

実行結果

解説

 3~6行目でフィールド変数のみを持つクラス「Computer2」が定義されています。
9行目でオブジェクト変数$comに、new演算子を利用してオジェクトを生成し代入しています。

 12行目で$comオブジェクトのフィールド変数「$os」にアクセスし文字列「WindowsXP」を格納します。
 13行目も$comオブジェクトのフィールド変数「$memory」にアクセスし数値「2048」を格納します。
   12: $com->os = "WindowsXP";
   13: $com->memory = 2048;

 12、13行の処理をイメージで表現すると、以下の図2.3.1のようになります。

図 2.3.1: フィールド変数へ値の格納

 23、24行目で$comオブジェクトのフィールド変数「$os」と「$memory」にアクセスし、各値を表示しています。
   23: echo "パソコンのOSは「" . $com->os . "」です。<br>";
   24: echo "メモリサイズは「" . $com->memory . "MByte」です。";

 23、24行目の処理をイメージで表現すると、以下の図2.3.2のようになります。

図 2.3.2: フィールド変数値の参照

 今回のサンプルではフィールド変数にアクセスする仕組みについて学習しました。1章の「クラスとオブジェクトの関係」でも案内していますが、1つのクラスからオブジェクトはいくつでも生成することができます。次の項では複数のオブジェクトを生成するサンプルを紹介します。

2.3.3 複数のオブジェクトを作成するプログラム

 同じクラスから生成された2つのオブジェクトの各々のフィールド変数に値を設定し、その結果を表示します。同じクラスから生成された複数のオブジェクトが、独立した個々のオブジェクトとなり、オブジェクト毎にフィールド変数の値を保持できることを学習しましょう。

ソースコード

ソース・フォルダー  :myproj_framework_basic/ch02
ファイル名      :manyObjects.php
アクセスURL    :http://localhost/myproj_framework_basic/ch02/manyObjects.php

➢ manyObjects.php

<?php
    // クラスの定義作成
    class Computer3{
        public $os;
        public $memory;
    }

    // 同じComputer3クラスからオブジェクトを2つ生成する
    $com1 = new Computer3();
    $com2 = new Computer3();

    // 個々のオブジェクトのフィールド変数に、各データを格納する
    $com1->os = "WindowsXP";
    $com1->memory = 2048;
    $com2->os = "Windows2000";
    $com2->memory = 512;
?>
<html>
    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    	<title>複数のオブジェクト作成</title>
    </head>
    <body>
    	<?php
        	// 個々のオブジェクトのフィールド変数の値を参照し、結果を画面に表示する
        	echo "パソコン1のOSは「" . $com1->os . "」です。<br>";
        	echo "メモリサイズは「" . $com1->memory . "MByte」です。<br>";
        	echo "パソコン2のOSは「" . $com2->os . "」です。<br>";
        	echo "メモリサイズは「" . $com2->memory . "MByte」です。";
    	?>
    </body>
</html>
	

実行結果

解説

 3~6行目でフィールド変数のみのメンバを持つクラス「Computer3」が定義されています。
   3 class Computer3{
   4 public $os;
   5 public $memory;
   6 }

 9、10行目でオブジェクト変数$com1と$com2に、オジェクトをnew演算子で生成し代入しています。雛形のクラスは同じ「Computer3」ですが、オブジェクト$com1と$com2は個々として独立します。
   9: $com1 = new Computer3();
   10: $com2 = new Computer3();

 9、10行目の処理をイメージで表現すると、以下の図2.3.3のようになります。

図 2.3.3: 複数オブジェクトを作成

 13、14行目でcom1オブジェクトのフィールド変数にアクセスし各値を格納します。
 15、16行目でcom2オブジェクトのフィールド変数にアクセスし各値を格納します。
   13: $com1->os = "WindowsXP";
   14: $com1->memory = 2048;
   15: $com2->os = "Windows2000";
   16: $com2->memory = 512;

 13~16行目の処理をイメージで表現すると、以下の図2.3.4のようになります。

図 2.3.4: 複数オブジェクトのフィールドへ値の格納

 26、27行目で$com1オブジェクトのフィールド変数「$os、$memory」にアクセスし、各値を表示しています。
 28、29行目で$com2オブジェクトのフィールド変数「$os、$memory」にアクセスし、各値を表示しています。
   26: echo "パソコン1のOSは「" . $com1->os . "」です。<br>";
   27: echo "メモリサイズは「" . $com1->memory . "MByte」です。<br>";
   28: echo "パソコン2のOSは「" . $com2->os . "」です。<br>";
   29: echo "メモリサイズは「" . $com2->memory . "MByte」です。";

 26~29行目の処理をイメージで表現すると、以下の図2.3.5のようになります。

図 2.3.5: 複数オブジェクトのフィールド変数値の参照

 今回のサンプルでは、生成されたオブジェクトの独立性について学習しました。
 次はフィールド変数へアクセスするだけではなく、メソッドへアクセスするサンプルを紹介していきます。

2.3.4 メソッドについて

 クラスには様々な目的に合わせ複数のメソッドを定義することができます。これまでの学習では、必要に応じて自作の関数を定義して利用していたと思います。オブジェクトを生成し呼び出すメソッドについても、定義の仕方は変わりません。

 また、今後はこれまでのようのオブジェクトから呼び出されるメソッドだけでなく、クラス全体に関連付けて定義するようなメソッドも用意する必要がある場面も出てきます。

 クラス全体に関連付けられたメソッドの場合、staticというキーワードを付けます。
 「static」が付いたメソッドのことを「クラスメソッド」、付かないメソッドを「インスタンスメソッド」と呼びます。なお、基本構文の初めについている「public」は「アクセス修飾子」と呼ばれ、他のクラスから利用される場合のアクセスを制限するためのキーワードの1種です。どこからでもアクセスが可能という意味を持っており、アクセスを制限しない場合には、「public」を付けるのが一般的です。
 「static」キーワードについては6章で、「public」のアクセス修飾子については3章で詳しく説明しますので、今は書式の通り覚えておいて下さい。

 メソッドのパターン
 これまでの自作の関数と同様に、戻り値の有無や引数の数や組み合わせで、基本は以下の4つに分類されます。作成する機能に応じて、適切なパターンを選べるようにしましょう。
 ・ 引数なし、戻り値なしの関数
 ・ 引数なし、戻り値ありの関数
 ・ 引数あり、戻り値なしの関数
 ・ 引数あり、戻り値ありの関数

 また、クラスで定義したメソッド内でフィールド変数や他のメソッドを呼び出す際には、以下のような書式で呼び出す必要があります。

 凡例:オブジェクト内のフィールド変数とメソッドへのアクセス方法
 2.2.1項で定義した「Computer」クラスを例にしています。
 下記のように起動時に呼び出すstart()メソッド内で、フィールド変数$osを呼び出すように仕様を変更する際は、フィールド変数名の先頭に$thisとアロー演算子->を付けます。

 クラス内でメソッドを定義している時点では、自身が内包されているオブジェクトの変数名がどういうものになるのかわかりません。そこで、メソッドから同じクラスのフィールド変数やメソッドを呼び出す際には、「このメソッドを呼び出したオブジェクト内の」という意味を持つ$this->を先頭に付けます。
 それでは、クラスに定義されたメソッドにアクセスするプログラムを次項で紹介します。

2.3.5 インスタンスメソッドを呼び出すプログラム

 インスタンスメソッドを呼び出して、フィールド変数の変更前と変更後の値を画面に表示させます。メソッドは引数なし、戻り値なしのパターンを定義しています。インスタンスメソッドの呼び出し方について学習しましょう。

ソースコード

ソース・フォルダー  :myproj_framework_basic/ch02
ファイル名      :instanceMethod1.php
アクセスURL    :http://localhost/myproj_framework_basic/ch02/instanceMethod1.php

➢ instanceMethod1.php

<?php
    // クラスの定義作成
    class Computer4{
        public $os;
        public $memory;

        // フィールド変数の値を表示するメソッド
        public function show(){
            echo "パソコンのOSは「" . $this->os . "」です。<br>";
            echo "メモリサイズは「" . $this->memory . "MByte」です。<br>";
        }
    }

    // Computer4クラスからオブジェクトを生成する
    $com = new Computer4();
?>
<html>
    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
    	<title>インスタンスメソッドを呼び出す</title>
    </head>
    <body>
    	<?php
    	    // データ格納前にメソッド呼び出し(1回目)
    	    echo "■1回目のメソッド呼び出し<br>";
    	    $com->show();

    	    // オブジェクトのフィールド変数に、各データを格納する
    	    $com->os = "WindowsXP";
    	    $com->memory = 2048;

    	    // データ格納後にメソッド呼び出し(2回目)
    	    echo "<br>■2回目のメソッド呼び出し<br>";
    	    $com->show();
    	?>
    </body>
</html>
	

実行結果

解説

 3~12行目でフィールド変数とメソッドを持つクラス「Computer4」が定義されています。
   3: class Computer4{
   4: public $os;
   5: public $memory;
   6:
   7: // フィールド変数の値を表示するメソッド
   8: public function show(){
   9: echo "パソコンのOSは「" . $this->os . "」です。<br>";
   10: echo "メモリサイズは「" . $this->memory . "MByte」です。<br>";
   11: }
   12: }

 15行目でオブジェクト変数$comにオジェクトをnew演算子で生成し代入しています。
   15: $com = new Computer4();

 15行目の処理をイメージで表現すると、以下の図2.3.6のようになります。

図 2.3.6: メソッドありオブジェクトの生成

 これまでのComputerクラスとは違いメソッドも定義されています。オブジェクトを生成することでメソッドにアクセスし利用が可能になります。

 26行目でフィールド変数にデータを格納する前に、1回目のshow()メソッド呼び出しを行っています。
   26: $com->show();

 26行目の処理をイメージで表現すると、以下の図2.3.7のようになります。

 ①「$com->show();」と記述し、変数$comに格納されているオブジェクトの場所情報からshow()メソッドにアクセスします。アクセス後は処理がshow()メソッド内に移ります。
 ②show()メソッド内部からフィールド変数「$os、$memory」にアクセスし値を取得します。
 ③②で取得した値をもとに画面に結果を出力します。
 ④showメソッド内の表示処理が終わると呼び出し元に処理が戻ります。

 オブジェクトのフィールド変数に初期値が設定されていないので、今回は空文字が出力されています。

 1回目のshow()メソッド呼び出しの後に、29、30行目でcomオブジェクトのフィールド変数に各値を格納しています。
   29: $com->os = "WindowsXP";
   30: $com->memory = 2048;

 フィールド変数にデータ格納後、33行目で2回目のshow()メソッド呼び出しを行っています。
   34: $com->show();

 34行目の処理をイメージで表現すると、以下の図2.3.8のようになります。
 ①「$com->show();」と記述し、変数$comに格納されているオブジェクトの場所情報からshow()メソッドにアクセスします。アクセス後は処理がshow()メソッド内に移ります。
 ②show()メソッド内からフィールド変数「$os、$memory」にアクセスし値を参照します。
 ③②で参照して取得した値を画面にを出力します。
 ④showメソッド内の表示処理が終わるとmainメソッド内に処理が戻ります。

図 2.3.8: オブジェクトからメソッドを再度呼び出す

 このプログラムのポイントはshowメソッドに「何度もアクセスできる」ことと、行う処理はあくまで「その時点」のフィールド変数の値を参照し、画面に結果を表示するということです。
 このようなメソッドを用意しておくことで、オブジェクト内のフィールド変数の値を確認する時に非常に便利になります。
 続いて次の項ではメソッドの呼び出しパターンについて、別のプログラムを紹介していきます。

2.3.6 オブジェクトの様々なメソッドを呼び出すプログラム

 オブジェクト内に定義されているメソッドから他のメソッドを呼び出します。さらに色々なパターンのメソッドを定義し使用しています。プログラムが長くなり若干複雑な流れをしていますが、迷わないように解説と解説内のポイントをよく読み学習していきましょう。

ソースコード

ソース・フォルダー  :myproj_framework_basic/ch02
ファイル名      :instanceMethod2.php
アクセスURL    :http://localhost/myproj_framework_basic/ch02/instanceMethod2.php

➢ instanceMethod2.php

<?php
    // クラスの定義作成
    class Computer5{
        public $os;
        public $memory;

        // メッセージとパソコン情報を表示するメソッド
        public function showComputer(){
            echo "パソコンの情報を表示します。<br>";
            // クラス内のshowメソッドを呼び出す
            $this->show();
        }

        // フィールド変数の値を表示するメソッド
        public function show(){
            echo "OSは「" . $this->os . "」です。<br>";
            echo "メモリサイズは「" . $this->memory . "MByte」です。<br>";
        }

        // フィールド変数よりOSの値を取得する
        public function getOs(){
            return $this->os;
        }

        // フィールド変数よりMemoryの値を取得する
        public function getMemory(){
            return $this->memory;
        }

        // フィールド変数に値を設定するメソッド
        public function setOsMemory($name, $size){
            $this->os = $name;
            $this->memory = $size;
            echo "OSを「" . $name . "」に、メモリサイズを「" . $size
            . "MByte」に変更しました。<br>";
        }
    }

    // Computer5クラスからオブジェクトを生成する
    $com = new Computer5();

    // オブジェクトのフィールド変数に、各データを格納する
    $com->os = "WindowsXP";
    $com->memory = 2048;
?>
<html>
    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
    	<title>様々なメソッドを呼び出す</title>
    </head>
    <body>
    	<?php
    	    // メソッドを利用してフィールド変数に格納しているデータを取得
    	    echo "パソコンのOSは「" . $com->getOs() . "」です。<br>";
    	    echo "メモリサイズは「" . $com->getMemory() . "MByte」です。<br>";

    	    // オブジェクトのフィールド変数に、各データを再格納する
    	    $com->setOsMemory("Windows2000", 512);

    	    // showComputerメソッド呼び出し
    	    $com->showComputer();
    	?>
    </body>
</html>
	

実行結果

解説

 3行~37行目にフィールド変数とメソッドを持つクラス「Computer5」が定義されています。
   3: class Computer5 {
   4: public $os;
   5: public $memory;
      …
      各種メソッド ※表2.3.2を参照
      …
   37: }

 この「Computer5」クラスには以下のメソッドが定義されています。色々なパターンのメソッドを設定している所がポイントになります。

表 2.3.1: Computer5クラス定義メソッド一覧

 40行目でオブジェクト変数$comにオジェクトをnew演算子で生成し代入しています。
   40: $com = new Computer5();

 43、44行目にフィールド変数に各値を格納しています。
   43: $com->os = "WindowsXP";
   44: $com->memory = 2048;

 54行目で変数$comのオブジェクト参照情報から「getOs()メソッド」を呼び出し、フィールド変数osの値取得してを画面にメッセージと共に表示します。
   54: echo "パソコンのOSは「" . $com->getOs() . "」です。<br>>";

 54行目の処理をイメージで表現すると、以下の図2.3.9のようになります。
 ①変数$comに格納されているオブジェクトの場所情報からアクセスして「getOs()メソッド」呼び出します。アクセス後は処理がgetOs()メソッド内に遷移します。
 ②getOs()メソッド内ではフィールド変数「$os」を参照します。
 ③フィールド変数「$os」を参照して取得できた値を、戻り値として呼び出し元に返します。
 ④呼び出し元に処理が戻り、戻り値の結果を画面にメッセージと共に表示します。

図 2.3.9: オブジェクトからgetOs()メソッドを呼び出す

 55行目も54行目と同じように変数$comのオブジェクトから「getMemory()メソッド」を呼び出し、フィールド変数$memoryの値を取得して画面にメッセージと共に表示します。
   55: echo "メモリサイズは「" . $com->getMemory() . "MByte」です。<br>";

 58行目で変数$comのオブジェクト内の「setOsMemory()メソッド」に各引数情報を渡して呼び出し、その引数情報をフィールド変数$osと$memoryに設定しています。
   58: $com->setOsMemory("Windows2000", 512);

 58行目の処理をイメージで表現すると、以下の図2.3.10のようになります。
 ①変数$comに格納されているオブジェクトの場所情報からアクセスして「setOsMemory()メソッド」を呼び出します。アクセス後は処理がsetOsMemory ()メソッドに遷移します。
 ②setOsMemory()メソッド内では引数で受け取った値をフィールド変数「$os、$memory」に格納します。
 ③設定内容の結果を画面に表示します。
 ④結果表示後に呼び出し元に処理が戻ります。

図 2.3.10: オブジェクトからsetOsMemory()メソッドを呼び出す

 ここでのポイントは呼び出された「setOsMemoryメソッド」に与えた引数の値がオブジェクト内のフィールド変数に格納される所です。毎回「オブジェクト変数名->フィールド変数名」でアクセスするのではなくフィールド変数に値を設定するメソッドを準備しておけば大変便利になります。
 今回のメソッドでは2つの値を引数に与えてフィールド変数に格納するものでしたが、個別に設定するメソッドを用意するのが一般的です。
 フィールド変数に値を設定するメソッドと、逆に値を参照して返してくれるメソッドのことをPHPでは「アクセサメソッド」と呼びます。詳しい説明は3章で行いますので、「アクセサメソッド」という言葉を覚えておいて下さい。

 61行目で変数$comのオブジェクトから「showComputer()メソッド」に呼び出して情報を表示しています。このshowComputer()メソッド内からさらにshow()メソッドが呼び出されています。
   61: com.showComputer();

 61行目の処理をイメージで表現すると、以下の図2.3.11のようになります。
 ①変数$comに格納されているオブジェクトの場所情報からアクセスして「showComputer()メソッド」を呼び出します。アクセス後は処理がshowComputer ()メソッドに遷移します。
 ②showComputerメソッド内で、固定のメッセージを画面に出力します。
 ③同じオブジェクト内からshow()メソッドを呼び出します。呼び出し後は処理がshow ()メソッドに遷移します。
 ④showメソッド内で各フィールド変数の値を画面に表示します。
 ⑤フィールド変数の値を表示後に再度showComputer()メソッドに処理が戻ります。
 ⑥showComputerメソッド内に戻った後は処理がもうないため、呼び出し元に処理が戻ります。

図 2.3.11: オブジェクトからshowComputer()メソッドを呼び出す

 ここでのポイントは同一のクラス内に定義されている、メソッド同士は自由に呼び合えるところです。但し「static」キーワードが付くと前提が変わってきます。「static」に関する説明は6章で詳しく説明します。

2.3.7 オブジェクト変数を別のオブジェクト変数で初期化(代入)するプログラム

 オブジェクト変数に別のオブジェクト変数を代入した場合、どのような動きをするか確認しましょう。

ソースコード

ソース・フォルダー  :myproj_framework_basic/ch02
ファイル名      :objectInitializationObjectVariable.php
アクセスURL    :http://localhost/myproj_framework_basic/ch02/objectInitializationObjectVariable.php

➢ objectInitializationObjectVariable.php

<?php
    // クラスの定義作成
    class Computer6{
        public $os;
        public $memory;

        // フィールド変数の値を表示するメソッド
        public function show(){
            echo "OSは「" . $this->os . "」です。<br>";
            echo "メモリサイズは「" . $this->memory . "MByte」です。<br>";
        }
    }

    // Computer6クラスからオブジェクトを生成する
    $com1 = new Computer6();

    // com1オブジェクトの各値を設定
    $com1->os = "WindowsXP";
    $com1->memory = 2048;
?>
<html>
    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
    	<title>別のオブジェクト変数で初期化</title>
    </head>
    <body>
    	<?php
    	    // オブジェクト変数com2を宣言と同時に別変数で初期化
    	    $com2 = $com1;
    	    echo "com2にcom1を代入しました。<br><br>";

    	    // com1のshowメソッドにアクセス
    	    echo "com1のさすパソコンの";
    	    $com1->show();

    	    // com2のshowメソッドにアクセス
    	    echo "com2のさすパソコンの";
    	    $com2->show();
    	?>
    </body>
	

実行結果

解説

 15目でComputer6ブジェクトを作成しています。18、19行目でフィールド変数$osと$memoryに各値を代入しています。
   15: $com1 = new Computer6();
   18: $com1->os = "WindowsXP";
   19: $com1->memory = 2048;

 29行目でオブジェクト変数com2の宣言と同時に、既に宣言済みの変数com1の値で初期化を行っています。
   29: $com2 = $com1;

 29行目の処理をイメージで表現すると、以下の図2.3.12のようになります。オブジェクト変数の代入を行うと格納されている場所情報をコピーすることになり、結果として同じオブジェクトを指し示すようになります。

図 2.3.12: オブジェクト変数同士の代入

 34、38行目ではオブジェクト実体の場所情報からshow()メソッドを呼び出してパソコン情報を表示しています
   34: $com1->show();
   38: $com1->show();

ポイント
  • オブジェクト変数には既に作成済みのオブジェクト変数を代入できるが、オブジェクト実体は同じものを参照する事になる。

NEXT>> 2.4 本章のまとめ