PHP超入門コース#13 クラス

はじめに

こんにちは。キノコードです。
「PHP超入門コース#13 クラス」について説明します。

クラスとは?

クラスにはインスタンスやコンストラクタなどの概念がでてきます。
私自身、プログラミングを勉強し始めたときに、これを理解するのに時間がかかりました。
私が何冊も書籍を読んで、こういう順番であれば理解しやすいというプロセスで説明します。
クラスを理解できた感動をみなさんにもお届けできればと思い、説明していきます。
まずクラスについて説明します。
クラスとは、「データ」と「処理」をまとめたものになります。
PHPでは、「データ」のことをプロパティといい、「処理」のことをメソッドといいます。

プロパティとメソッド

プロパティは、クラス内で定義された変数のことです。
プロパティは、変数と同じように、数値や文字列を代入したり、参照したりすることができます。
プロパティと変数の違いは、クラスの外にあるかクラスの中にあるかの違いです。
プロパティには、アクセス修飾子をつける必要があります。
簡単に説明すると、アクセス修飾子はどこからアクセス可能であるかを決めるものになります。
アクセス修飾子には、public(パブリック)、protected(プロテクテッド)、private(プライベート)があります。
publicは、どこからでもアクセス可能です。
protectedは、クラス自身、継承したクラス、親クラスからのみアクセスできます。
privateは、同じクラスの中でのみアクセス可能です。
次にメソッドについて説明します。
前のレッスンで関数は、いろいろな「処理」をまとめて1つにしたものと説明しました。
メソッドも関数と同じで、いろいろな「処理」をまとめて1つにしたものです。
簡単にいうと、メソッドは、クラス内に定義された関数です。
まとめると、プロパティはクラス内の変数、メソッドはクラス内の関数ということになります。

クラスの定義

クラスを作ることをクラスを定義すると言います。
このレッスンでどんなクラスを定義するか説明します。
クラス名はStudentとします。
次に、数学と英語の点数の平均を計算するavgというメソッドを定義します。
コードを書いていきましょう。


<?php
  class Student {

    function avg() {
      echo ((80 + 70) / 2)."\n";
    }
  
  }

まずclassと書いて、次にクラス名を書きます。
今回はStudentというクラス名なので、Student。
クラス名の最初の文字は小文字でも定義はできますが、最初の文字を大文字するのは、PHPの慣習となっています。
クラス名の最初の文字は大文字にしましょう。
波括弧を書いて改行です。

次にメソッドを定義していきます。
数学と英語の点数の平均を計算するメソッドです。
まず、functionを書きます。
平均を計算するので、平均という意味のaverageを省略して、avgというメソッド名にします。
次に丸括弧を記述します。引数がある場合は、丸括弧内に引数を記述します。
引数は、関数と同じで引数がなくてもよいです。
また、複数の引数を定義してもよいです
今回はメソッドに渡す引数がないので、引数は記述しません。
丸括弧の次は、波括弧。改行です。
波括弧の中に、数学が80点と、英語が70点を取れたとして、それらを足して2で割ります。
表示させるためにechoでくくりましょう。
引数は、関数と同じで引数がなくてもよいです。
また、複数の引数を定義してもよいです
今回はメソッドに渡す引数がないので、引数は記述しません。
これで、クラスを定義することができました。
クラスを実際に使ってみたいと思いますが、クラスはこのままでは使うことができません。
クラスは、クラスから作られたインスタンスを変数に代入してから使います。
クラスは、インスタンスになって初めて使えるようになります。
コードを書いて、クラスの使い方をみていきましょう。


<?php
  class Student {

    function avg() {
      echo ((80 + 70) / 2)."\n";
    }
  
  }

  $a001 = new Student();
  $a001->avg();

数学が80点、英語が70点という点数は、aという学級の出席番号001番の人がとったとします。
変数名をa001とします。
イコールを書いて、new、クラス名、丸括弧、セミコロンを書きます。
これで、クラスを使えるようになりました。
クラスを使えるような状態にすることを「インスタンス化」といいます。
インスタンスとは、実体という意味です。
なので、インスタンス化とは、実体化という意味です。
つまり、インスタンス化とは、クラスという型から、インスタンスという実際に使える「モノ」を作ることをいいます。
変数にインスタンスを代入して、インスタンスとして使えるようになったa001は、これからa001インスタンスと呼ぶことにします。

次にメソッドの実行方法についてです。
a001のあとにハイフン、>、メソッド名です。
ハイフン(-)、大なり(>)、をつけることで、インスタンスのプロパティやメソッドを参照できるようになります。
丸括弧とセミコロンも忘れないでください。
実行してみます。
平均点の75点が表示されました。


<?php
  class Student {

    function avg($math, $english) {
      echo (($math + $english) / 2)."\n";
    }
  
  }

  $a001 = new Student();
  $a001->avg(80, 70);

ここまでは、80点と70点を直接、メソッド内に記述していました。
これだと生徒が変わるごとにメソッドの書き換えが必要です。
引数で渡して計算できるようにしましょう。
そうすることで、クラスの書き換えは不要になり、クラスを使い回すことができます。
クラス内に記述しているメソッドの1番目の引数をmathとします。
2番目の引数をenglishとします。
そのmathとenglishの引数を、echoのところに記述します。
avgメソッドに80点と70点を渡して実行してみましょう。
75点となるはずです。
75が表示されました。


<?php
  class Student {

    function avg($math, $english) {
      echo (($math + $english) / 2)."\n";
    }
  
  }

  $a001 = new Student();
  $a001->avg(30, 70);

メソッドに渡す引数を30点と70点にしてみましょう。
平均の50が表示されるはずです。
実行してみましょう。
50が表示されました。


<?php
  class Student {

    public $name;

    function avg($math, $english) {
      echo (($math + $english) / 2)."\n";
    }
  
  }

  $a001 = new Student();
  $a001->avg(30, 70);
  $a001->name = "sato";
  echo $a001->name."\n";

次にプロパティについてみていきましょう。
プロパティは、クラス内に定義された変数のことです。
プロパティを定義していきます。
アクセス修飾子のpublic を書いて、プロパティ名、セミコロン。
佐藤さん、鈴木さんといったような名前を代入したいので、プロパティ名をnameにします。
次に、インスタンスのプロパティに値を代入します。
a001に「->」。プロパティ名を書いて、値を代入します。
値はsatoさんとしましょう。
これでプロパティの定義はおわりです。
echoで表示させてみましょう。
実行してみましょう。
メソッドの結果の75とプロパティのsatoが表示されました。


<?php
  class Student {

    public $name;

    function avg($math, $english) {
      echo (($math + $english) / 2)."\n";
    }
  
  }

  $a001 = new Student();
  $a001->avg(30, 70);
  $a001->name = "sato";
  echo $a001->name."\n";
  echo $a001->gender."\n";

仮に、性別という意味の というまだ定義していないプロパティを表示させてみましょう。
定義していないので、何も表示されません。
実行してみましょう。
何も表示されませんでした。
このように未定義のプロパティは何も表示されません。


<?php
class Student {

  public $name;

  function avg($math, $english) {
    echo (($math + $english) / 2)."\n";
  }
}

$a001 = new Student();
$a001->name = "sato";
$a001->avg(80, 70);
echo $a001->name."\n";

$a002 = new Student();
echo $a002->name."\n";

また、a002というインスタンス名でインスタンス化をしたあとに、
nameのプロパティを表示させてみましょう。
実行してみましょう。
何も表示されませんでした。
このようにプロパティは、インスタンスごとに存在します。
逆の言い方をすれば、インスタンスごとに、プロパティを定義しなければなりません。
つまり、インスタンスごとにプロパティが存在するので、新しいインスタンスを作るごとに、プロパティを定義する必要があります。
そのため、10個インスタンスを作ったとすると、インスタンスごとにプロパティを10個定義する記述をしなければなりません。
先ほどの例でいうと、「 $a001->name」のような記述をインスタンスごとに10個、記述しなければなりません。
その不便さを解消するものがコンストラクタです。
コンストラクタは、インスタンス化するときに呼び出されるメソッドのことです。
コンストラクタは、初期化メソッドともいいます。
初期化メソッドは、インスタンス化をすれば、必ず実行されるメソッドです。
そのため、あとから使うプロパティは、初期化メソッドで自動的に作っておけばよいのです。


<?php
class Student {

  public $name;

  public function __construct() {

  }
  function avg($math, $english) {
    echo (($math + $english) / 2)."\n";
  }
}

$a001 = new Student();
$a001->name = "sato";
$a001->avg(80, 70);
echo $a001->name."\n";

$a002 = new Student();
echo $a002->name."\n";

初期化メソッドの記述方法をみていきましょう。
まず、public、functionを記述します。
次に、アンダースコアを2つ、constructorと記述し、丸括弧。次に波括弧を記述します。
これで初期化メソッドの記述は終わりです。


<?php
class Student {

  public $name;

  public function __construct() {
    $this->name = "tanaka";
  }
  function avg($math, $english) {
    echo (($math + $english) / 2)."\n";
  }
}

$a001 = new Student();
$a001->name = "sato";
$a001->avg(80, 70);
echo $a001->name."\n";

$a002 = new Student();
echo $a002->name."\n";

波括弧の中に、$this、ハイフン、>、nameを書きます。
$thisというキーワードが出てきました。
$thisと書くことで、$thisにインスタンスが代入されます。
ここは難しい理屈なので、そういう仕組みになっているのだと思って覚えておきましょう。
ここでは、ダブルクォーテーション2つで、”tanaka”を代入させておきましょう。
では、インスタンス化をして、a001とa002の中をみてみましょう。
avgメソッドの記述は消しておきます。


<?php
class Student {

  public $name;

  public function __construct() {
    $this->name = "tanaka";
  }
  function avg($math, $english) {
    echo (($math + $english) / 2)."\n";
  }
}

$a001 = new Student();
$a001->name = "sato";
echo $a001->name."\n";

$a002 = new Student();
echo $a002->name."\n";

先ほど表示されなかったa002のnameにtanakaが入っているはずです。
実行してみましょう。
satoとtanakaが表示されました。


<?php
class Student {

  public $name;

  public function __construct($name) {
    $this->name = $name;
  }
  function avg($math, $english) {
    echo (($math + $english) / 2)."\n";
  }
}

$a001 = new Student();
$a001->name = "sato";
echo $a001->name."\n";

$a002 = new Student();
echo $a002->name."\n";

プロパティは、インスタンス化と同時に代入することもできます。
初期化メソッドの第一引数に$nameという引数を記述します。
ダブルクォーテーションで”tanaka”を代入していたところに、$nameを記述します。
イメージとしては、第一引数の$nameを初期化メソッド内の$nameが受けて、それをここ($this->name)に代入します。
では、a001にインスタンス化と同時に”sato”を、a002にインスタンス化と同時に”tanaka”を渡してみましょう。


<?php
class Student {

  public $name;

  public function __construct($name) {
    $this->name = $name;
  }
  function avg($math, $english) {
    echo (($math + $english) / 2)."\n";
  }
}

$a001 = new Student("sato");
echo $a001->name."\n";

$a002 = new Student("tanaka");
echo $a002->name."\n";

表示させてみましょう。
satoさんとtanakaさんが表示されました。
以上がコンストラクタの使い方です。
このクラスの便利なところはどんなところでしょうか?
クラスは一度、定義しておけば、あとからいくらでもインスタンスを作ることができます。
車を作る「設計図」がクラス、たい焼きを作る「金型」がクラスと表現したりもします。
もう1つ表現するなら、クラスは、パソコンで使うコピペです。
コピペでどんどんインスタンスを作ることができます。
もしクラスがなければ、生徒ひとりひとりのためにStudentクラスを書かなければいけないので面倒です。
しかしクラスがあるから、コピペのように各生徒のインスタンスを作ることができます。
クラスがあるから効率よくプログラミングすることができます。