クラスの定義
class
キーワードでクラスを定義- プロパティーは
private/protected/public
で宣言 - コンストラクターは
public function __construct()
で定義(アンダースコア2つ) - メソッドは
public/protected/private function
で定義 - インスタンスの生成は
new クラス名(...);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php class MyClass { private $property; public function __construct() { ..... } public function method() { ..... } } $instance = new MyClass(); |
プロパティー
宣言・定義
プロパティー宣言時に値の初期値を定義可能。
private/protected/public プロパティー = 初期値;
参照・代入
クラス内でのプロパティー参照・代入
$this->プロパティー名($除き)
publicプロパティーのインスタンスからの参照・代入
インスタンス変数->プロパティー名($除き)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php class MyClass { public $public_property; private $private_property; public function __construct($private_property) { $this->private_property = $private_property; } public function method() { echo $this->private_property . '<br>'; } } $instance = new MyClass('Private'); $instance->public_property = 'Public'; $instance->method(); echo $instance->public_property; |
メソッド
メソッドはオーバーロードできない
PHPでは、異なるシグネチャーでメソッドをオーバーロードすることはできない。コンストラクターについても同じくオーバーロードできない。
以下のクラスではメソッドをシグネチャーの違いによってオーバーロードしようとしている。
1 2 3 4 5 6 7 8 9 10 11 |
<?php class MyClass { public function method($arg) { echo $arg . "\n"; } public function method() { echo '0\n'; } } |
しかし複数宣言はできないというエラーになる。
1 |
PHP Fatal error: Cannot redeclare MyClass::method() in /home/vagrant/test/test.php on line 8 |
デフォルト引数は使える
異なるシグネチャーのメソッドは、デフォルト引数を使うことで実現できる。
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php class MyClass { public function method($arg1=0, $arg2=0) { echo $arg1 * 10 + $arg2 . "\n"; } } $instance = new MyClass(); $instance->method(2, 1); // 21 $instance->method(2); // 20 $instance->method(); // 0 |
デフォルト引数が指定されている場合に引数を指定すると、先頭の引数から値が設定されていく。引数名を指定して任意の引数の実を指定することはできない。
1 2 |
$instance->method($arg1=4); // 40 $instance->method($arg2=4); // 40 |
コンストラクター/デストラクター
public function __construct(...) { ... }
public function __destruct(... { ... }
- いずれも動詞形で、先頭にアンダースコアを2つつける
クラスを継承した場合、コンストラクター/デストラクターを定義しなければ、親クラスのそれらが呼ばれるが、定義した場合には明示的に親クラスのコンストラクター/デストラクターを呼び出す必要がある。
parent::__construct(...)
parent::__destruct(...)
staticプロパティー
プロパティーをstatic
宣言することで、クラスとして保持されるようになる。
private static
宣言
クラス外からアクセス不能なクラスレベル変数。
- クラス内で(すなわち各インスタンスから)
self::プロパティー名($付き)
でアクセスできる - 全インスタンスで1つの値を共有する
以下の例では全インスタンスに共通のカウンターをクラス変数として持ち、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php class MyClass { private static $count = 0; public function __construct() { self::$count++; echo self::$count . "個目のインスタンスを生成\n"; } } $instance1 = new MyClass(); $instance2 = new MyClass(); $instance3 = new MyClass(); // 1個目のインスタンスを生成 // 2個目のインスタンスを生成 // 3個目のインスタンスを生成 |
public static
宣言
クラス外からもアクセス可能なクラスレベル変数。
- クラス内外を問わず、
クラス名::プロパティー名($付き)
でアクセスできる
以下のコードではクラスレベルのカウンターをpublic
宣言し、クラス外からもアクセス可能としている。
8行目はself::$count
でもよいが、クラス外からもアクセス可能なことを強調してMyClass::$count
としている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php class MyClass { public static $count = 0; public function __construct() { self::$count++; echo MyClass::$count . "個目のインスタンスを生成\n"; } } $instance1 = new MyClass(); echo MyClass::$count . "個のインスタンス\n"; $instance2 = new MyClass(); echo MyClass::$count . "個のインスタンス\n"; $instance3 = new MyClass(); echo MyClass::$count . "個のインスタンス\n"; // 1個目のインスタンスを生成 // 1個のインスタンス // 2個目のインスタンスを生成 // 2個のインスタンス // 3個目のインスタンスを生成 // 3個のインスタンス |
staticメソッド
public static
宣言
クラス外からもアクセス可能なクラスレベルメソッド。
以下のコードでは、private static
宣言されたカウンターを、public static
宣言されたメソッドで参照している。このようにすると、private
宣言されたカウンターが外部で変更される恐れがなくなる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php class MyClass { private static $count = 0; public static function getInstanceCount() { return self::$count; } public function __construct() { MyClass::$count++; } } $instance1 = new MyClass(); echo MyClass::getInstanceCount() . "個のインスタンス\n"; $instance2 = new MyClass(); echo MyClass::getInstanceCount() . "個のインスタンス\n"; $instance3 = new MyClass(); echo MyClass::getInstanceCount() . "個のインスタンス\n"; // 1個のインスタンス // 2個のインスタンス // 3個のインスタンス |
private static
宣言
private
宣言したメソッドはstatic
宣言されたクラスメソッドでもインスタンスメソッドでもあまり変わりはないように思える。
こちらの記事で、staticメソッドからインスタンスのプロパティーにアクセスできないことを利用して、メソッドが余計な副作用を持たないことを明示できるとあって、なるほどと思った。