PHPの「クラス」と「インスタンス」――「オブジェクト指向」の基礎中の基礎Web業界で働くためのPHP入門(13)(3/3 ページ)

» 2017年12月14日 05時00分 公開
前のページへ 1|2|3       

クラスの形

 データをまとめる方法としてクラスを導入しました。実は、このクラスの役割はデータをまとめるだけではありません。ここからは、その点を見ていきましょう。

クラスは処理を含めることができる

 リスト5で関数の引数をクラス型にし、複数のデータをまとめて渡すことで少しスッキリしました。しかし、まだ無駄があります。それは「インスタンスへデータを格納すること」「データを処理してもらう関数にデータが格納されたインスタンスを渡すこと」の2つ、つまり、データと処理を結び付けるのを実行部分で行っていることです。

図5 データと処理を実行部分で結び付けている

 どうせクラス内のデータを使って処理を行うのなら、処理そのものをクラス内に含められれば全てがクラス内で完結し、便利です。

図6 クラス内に処理を含める

 では、TestScoreクラスをそのように改良したTestScoreWithMethodクラスを作成してみましょう。クラス作成のルールにのっとって、これは、TestScoreWithMethod.phpファイルに記述します。

<?php
class TestScoreWithMethod
{
    public $name = "";
    public $math = 0;
    public $english = 0;
    public $japanese = 0;
 
    public function printScore(): void
    {
        $sum = $this->math + $this->english + $this->japanese;
        $ave = $sum / 3;
        print($this->name."さんの合計: ".$sum." 平均: ".$ave."<br>");
    }
}
リスト6 phplesson/chap13/TestScoreWithMethod.php

 これが、クラスの形です。クラスにはデータと処理を一緒に含めることができます。そして、データは変数と、処理は関数と同じ記述方法です(ただしpublicが付きます)。ただ、名称が変わります。クラス内のデータ部、つまり変数のことを「プロパティ」、処理部、つまり関数のことを「メソッド」といいます。そして、プロパティとメソッドを合わせて「メンバ」といいます。

 構文としてまとめると以下のようになります。

構文 クラス

class クラス名

{

  public 変数名; ← プロパティ

    :

  public function メソッド名(引数) ←メソッド

  {

    処理;

  }

    :

}


メンバの記述順序は不問

 ところで、プログラムでは、記述した順序通りに処理されることは今までの解説で理解していると思います。従って、実行部分や関数内ではソースコードの記述順序は大切です。これはメソッド内でも同じです。

 ところが、クラス内のメンバ同士の記述順序は不問です。例えば、リスト6は以下のように記述しても問題なく動作します。

class TestScoreWithMethod
{
    public $name = "";
    public $math = 0;
    public function printScore()
    {
        :
    }
    public $english = 0;
    public $japanese = 0;
}

 とはいっても、リスト6のようにプロパティはプロパティで、メソッドはメソッドでまとめて記述した方が読みやすいです。

クラス内アクセスはthis

 ここでリスト6で追加したメソッドを見てみましょう。基本の処理はリスト5のprintScore()関数と同じですが、違うところがあります。

 まず、リスト5のprintScore()は外部からデータをもらう必要があるため、引数が必要でした。一方、リスト6のprintScore()メソッドはクラス内部のプロパティを使うため引数は不要です。

 そのクラス内部のメンバにアクセスするには「$this」を使います。リスト6の11行目が該当します。

 「$this」というのは自分自身を指します。例えば、「$taro->name」というのは変数$taroが表すインスタンス中のプロパティnameです。これはインスタンスを外から見た状態です。一方、「$this->name」というのは自分自身のインスタンスの中のプロパティnameです。こちらはインスタンスを中から見た状態です。

図7 たろうくんのインスタンスを外から見ると$taroだが中から見ると$this

メソッドもプロパティと同じようにアクセス

 では、メソッドが追加されたTestScoreWithMethodクラスを使うように実行部分を書き換えましょう。以下のuseTestScoreWithMethod.phpを作成し、実行してください。

<?php
require_once("TestScoreWithMethod.php");
 
$taro = new TestScoreWithMethod();
$taro->name = "たろう";
$taro->math = 87;
$taro->english = 92;
$taro->japanese = 74;
$taro->printScore();
 
$hanako = new TestScoreWithMethod();
$hanako->name = "はなこ";
$hanako->math = 95;
$hanako->english = 79;
$hanako->japanese = 83;
$hanako->printScore();
リスト7 phplesson/chap13/useTestScoreWithMethod.php

 実行結果はリスト1と同じです。

 TestScoreWithMethodクラスを使うので、ファイルの読み込み部分である2行目と、このクラスをnewする4行目と11行目が変更になっています。

 さらに、表示処理を行っていたprintScore()がTestScoreWithMethodクラスのメソッドになったので、単にprintScore()と記述するのではなく、「$taro->printScore()」や「$hanako->printScore()」という記述になっています。これは、それぞれ$taroインスタンスのメソッドprintScore()、$hanakoインスタンスのメソッドprintScore()を呼び出す記述です。

 このように、メソッドもプロパティと同様に「変数名->メンバ名」でアクセスできます。もしメソッドに引数が必要でしたら、()内に記述することで渡すことができます。

次回もオブジェクト指向の続き

 次回もこの続きとして、クラスの構文を拡げ、アクセス修飾子とアクセサメソッド、コンストラクタなどについて扱います。

今回のサンプルコード

 今回のサンプルコードはこちらからダウンロードできます。

前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

AI for エンジニアリング
「サプライチェーン攻撃」対策
1P情シスのための脆弱性管理/対策の現実解
OSSのサプライチェーン管理、取るべきアクションとは
Microsoft & Windows最前線2024
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。