カテゴリー:
クラスとオブジェクト
閲覧数:440 配信日:2017-02-23 10:02
アクセス経路2種類
インスタンスオブジェクト経由アクセス
・インスタンスオブジェクト生成が必要
・「->(アロー演算子)」を用い、生成したオブジェクト経由で「インスタンスメンバ」へアクセス
クラス経由アクセス
・オブジェクト生成は不要
・「::(スコープ演算子)」を利用し、「クラスメンバ」へ直接アクセス
メソッド
クラスで定義されている関数
・メンバ関数
・「インスタンスメソッド」と「クラスメソッド」の2種類存在
メソッド分類2種類
インスタンスメソッド
・インスタンスオブジェクトに所属する関数
・クラス定義されている関数の内、静的(static)でないもの
・インスタンス(オブジェクト)を通してアクセスする
クラスメソッド
・クラスに所属する関数
・静的メソッド
・クラス定義されている関数の内、静的(static)なもの
・インスタンス化せず(クラスのインスタンスオブジェクトを生成せず)にアクセス
「$this」の利用可否
利用可
・インスタンスメソッド
→ インスタンスを生成し、そのメソッド内で「self::」または「parent::」を使用してコールした場合
利用不可
・「クラスメソッド」としてコールされた場合
・「インスタンスオブジェクト」は生成されていないため、メソッド内でオブジェクトへのリファレンスを保持する「$this」は利用不可
「self::」「parent::」
「クラスメソッド」がアクセスできるのは?
・「クラスメンバ」のみ
・具体的には、「self::」を用いて「self::$static_public_property」や「self::static_public_method()」のようにアクセスする
・ちなみに、「クラスメソッド」でない「インスタンスメソッド」もこれでコールできる
・しかし、この場合にコールされるのは「インスタンスメソッド」となる(当然、「クラスメソッド」からのアクセスの場合は「クラスメソッド」としてコールされる)
「static修飾子」と「アクセス制限修飾子」の順番
・定義時に指定する「static修飾子」と「アクセス制限修飾子」の順番は任意。ex) 「static public $v」 でも、「public static $v」でも可。
コンストラクタ
・「スタティック」宣言できない
・そもそもスタティックにコールされることを想定していない
<pre>
<?php
class A{
public $public_v = "public_vメンバ変数";
static public $static_public_v = "static_public_vメンバ変数";
public function public_method(){
return "public_method()";
}
static public function static_public_method(){
return "static_public_method()";
}
public function get_static_public_v(){
#通常メソッド内でクラスメンバ参照
return self::$static_public_v;
}
static public function get_public_v(){
#スタティックメソッド内でインスタンスメンバ参照
return $this->public_v;
}
}
/*
class SKY{
#①コンストラクタをスタティック宣言しようとすると、Fatal error: Constructor SKY::SKY() cannot be staticとなる。コンストラクタは「スタティック」宣言できない(そもそもスタティックにコールされることを想定しないため)
static public function SKY(){
//empty
}
}
*/
#②インスタンスオブジェクト生成
$a = new A;
echo "■③インスタンスオブジェクト経由アクセス\n";
echo "▼インスタンスプロパティ取得\n";
echo '$a->public_v : ', $a->public_v, "\n\n";
echo "▼クラスプロパティ取得\n";
echo '$a->static_public_v : ', $a->static_public_v, "×「スタティック」宣言したプロパティは完全に「クラスプロパティ」となるため、「インスタンスプロパティ」として参照することが出来なくなる。\n\n";
echo "▼インスタンスメソッド取得\n";
echo '$a->public_method() : ', $a->public_method(), "\n\n";
echo "▼クラスメソッド取得 ※可読性の観点から、クラス関数へはアロー演算子でアクセスしない方がよい\n";
echo '$a->static_public_method(): ', $a->static_public_method(), "\n\n
";
echo "■④クラスアクセス\n";
echo "▼インスタンスプロパティ取得\n";
echo 'A::$public_v : '/*, A::$public_v*/, "×「インスタンスプロパティ」を「クラスプロパティ」として参照することはできない。【Fatal error: Access to undeclared static property: A::$public_v】\n\n";
echo "▼クラスプロパティ取得\n";
echo 'A::$static_public_v : ', A::$static_public_v, "\n\n";
echo "▼インスタンスメソッド取得 ※static でないメソッドを静的呼出ししているので、限りなくまちがいに近い\n";
echo 'A::public_method() : ', A::public_method(), "\n\n";
echo "▼クラスメソッド取得\n";
echo 'A::static_public_method() : ', A::static_public_method(), "\n\n
";
echo "■⑤インスタンスオブジェクト経由アクセス\n";
echo "▼インスタンスプロパティ更新\n";
$a->public_v = "public_vメンバ変数更新";
echo "▼インスタンスプロパティ取得\n";
echo '$a->public_v : ', $a->public_v, "\n\n
";
echo "■⑥クラスアクセス\n";
echo "▼クラスプロパティ更新\n";
A::$static_public_v = "static_public_vメンバ変数更新";
echo "▼クラスプロパティ取得\n";
echo 'A::$static_public_v : ', A::$static_public_v, "\n\n
";
echo "■⑦新たなオブジェクトb生成\n\n
";
$b = new A;
echo "■⑧インスタンスオブジェクト経由アクセス\n";
echo "▼インスタンスプロパティ取得\n";
echo '$b->public_v : ', $b->public_v, " …「aオブジェクトに対するインスタンスプロパティ」更新は、「bオベジェクトのインスタンスプロパティ」とは関係がない\n\n
";
echo "■⑨インスタンスオブジェクト(インスタンスメソッド)経由アクセス\n";
echo "▼クラスプロパティ取得\n";
echo '$a->get_static_public_v() : ', $a->get_static_public_v(), " …「クラスに対するプロパティ」更新は、そのクラスから生成される全てのオブジェクトが影響を受ける(クラスプロパティとインスタンスオブジェクトは無関係)\n";
echo '$b->get_static_public_v() : ', $b->get_static_public_v(), " …「クラスに対するプロパティ」更新は、そのクラスから生成される全てのオブジェクトが影響を受ける(クラスプロパティとインスタンスオブジェクトは無関係)\n\n
";
echo "■⑩クラスアクセス(クラスメソッド)経由\n";
echo "▼インスタンスプロパティ取得\n";
echo 'A::get_public_v() : '/*, A::get_public_v()*/, "×【Fatal error: Using $this when not in object context】「オブジェクトではないから「\$this」は使えない」 \n\n
";
echo "■⑪インスタンスオブジェクト(クラスメソッド)経由アクセス\n";
echo "▼インスタンスプロパティ取得\n";
echo '$a->get_public_v() : '/*, $a->get_public_v()*/,"×【Fatal error: Using $this when not in object context】「オブジェクトではないから「\$this」は使えない」 \n";
?>
▼クラス継承時の注意事項
子クラスで親クラスと同名のプロパティを再定義する場合も、メソッドをオーバーライドする場合も、「クラスメンバ」だったものを「インスタンスメンバ」にしたり、「インスタンスメンバ」だったものを「クラスメンバ」に変更することは出来ない。
また、“「パブリック」な「スタティックプロパティ」”に関して、何れの場合も(子クラスで「スタティック」宣言したとしても)子クラスで再定義することができない。