static修飾子

クラスとオブジェクト

static修飾子とは?

 状態:-  閲覧数:4,237  投稿日:2010-05-10  更新日:2018-01-18  
クラス メンバーが、「クラスのインスタンス」ではなく「クラス」に属していることを宣言する修飾子
・「通常のメンバー」は、「インスタンスメンバー」として「インスタンスオブジェクト」に属している

クラスメンバー」とは?
・「静的メンバー」と同義語
→ クラスそのものに属する「プロパティ」「メソッド」のこと

静的メンバーの対義語
・通常メンバー

static
・スタティック
・静的


書式


定義
・メソッドやプロパティにstatic キーワード をつけるだけ
・プロパティをstaticにする意味はあまりないので普通はstaticにしない
・呼び出しは、クラス外より行なうので、アクセス修飾子は必ず「public」とする

呼出
・インスタンスオブジェクトを生成せず、直接「クラス名::メソッド名()」で呼び出す
クラス名::メソッド名()
・クラス内よりアクセスする場合
self::$プロパティ
self::メソッド()


日本語で例えてみる

 閲覧数:370 投稿日:2016-12-09 更新日:2017-10-10 

「日本人」クラスを設計


class 日本人 {
}


氏名


プロパティ
・日本人なら誰もが持っていて、みな異なる(同じ場合もある)
・個々のインスタンス(例、山田太郎、鈴木花子)で異なる
class 日本人 {
 氏名;
}


生年月日


プロパティ
・日本人なら誰もが持っていて、みな異なる(同じ場合もある)
・個々のインスタンス(例、山田太郎1990-01-01、鈴木花子2000-02-02)で異なる
class 日本人 {
 氏名;
 生年月日;
}


年齢


メソッドより求める
・日本人なら誰もが持っていて、みな異なる(同じ場合もある)
・個々のインスタンス(例、山田太郎27、鈴木花子17)で異なる
・プロパティを利用して算出可能
class 日本人 {
 氏名;
 生年月日;
 年齢計算 function{生年月日プロパティを使用して求める};
}


公用言語


staticプロパティ
・全ての日本人で共通
・すべてのインスタンス(例、山田太郎、鈴木花子)で共通なもの(であるがゆえに1つだけあればよい代物)
class 日本人 {
 static 公用言語;
 氏名;
 生年月日;
 年齢計算 function{生年月日を使用して求める};
}


まとめ1


「氏名」「生年月日」「年齢」
・「日本人」ではなく、個々のインスタンス(例、山田太郎、鈴木花子)に属している
→ staticを付与しない

「公用言語」
・「日本人」に属している
→ staticを付与


まとめ2


インスタンスメソッド内より
・staticプロパティとstaticメソッドは呼出可
山田太郎の公用語を求める

staticメソッド内より
・普通のプロパティと普通のメソッドは呼び出し不可
日本人に共通な氏名を求める
日本人に共通な生年月日を求める
日本人に共通な年齢を求める


「static修飾子」付与 → クラスメソッド

 閲覧数:442 投稿日:2016-12-09 更新日:2017-07-15 

クラスメソッド


クラスで定義されている関数の内、静的(static)なもの
・インスタンス化せずにアクセス可能

=静的メソッド
・インスタンス化せずにアクセス可能


クラスメソッド定義例


class Calculator{
 public static function addition($int1, $int2){
 }
 public static function substraction($int1, $int2){
 }
 public static function getAverage($intVals){
 }
}


クラスメソッド呼び出し例


Calculator::addition(10, 1);
Calculator::substraction(10, 1);
Calculator::getAverage($intVals);


クラスメソッドをメンバーとして持つクラス例


計算処理クラス

class Calculator{
   // 足し算
   public static function addition($int1, $int2){
       return $int1 + $int2;
   }

   // 引き算
   public static function substraction($int1, $int2){
       return $int1 - $int2;
   }

   // 平均値を求める
   public static function getAverage($intVals){
       if (false == is_array($intVals)) {
           return false;
       }
       $cnt = count($intVals);
       $total = 0;
       foreach ($intVals as $int) {
           $total += $int;
       }
       $average = $total / $cnt;
       return $average;
   }
}

$answer = Calculator::addition(10, 1);
var_dump($answer);

$answer = Calculator::substraction(10, 1);
var_dump($answer);

$intVals = array(1, 2, 3, 4, 5, 6, 7);
$answer = Calculator::getAverage($intVals);
var_dump($answer);


▼結果
int(11)
int(9)
int(4)




階層関係 相関イメージ

 閲覧数:397 投稿日:2017-01-17 更新日:2017-02-19 

メンバ(内容別)


メンバ
 |
 +--- プロパティ
 |      |
 |      +--- インスタンスプロパティ
 |      |
 |      +--- クラスプロパティ
 |
 +--- メソッド
        |
        +--- インスタンスメソッド
        |
        +--- クラスメソッド  


メンバへのアクセス方式(書式)


メンバへのアクセス方式
 |
 +--- 「インスタンスオブジェクト経由アクセス」→「->(アロー演算子)」利用。オブジェクト生成必要
 |
 +--- 「クラスアクセス」→「:(スコープ演算子)」利用。オブジェクト生成不要


メンバへのアクセス(プロパティ)


class A
{
 public $p;
 public static $s;
}
$a = new A();
メンバへのアクセス(プロパティ)
 |
 +---  $a->p  ◯「オブジェクト経由アクセス」インスタンスプロパティ
 |
 +---  $a->s  ×「オブジェクト経由アクセス」クラスプロパティ  ※「スタティック」宣言したプロパティは完全に「クラスプロパティ」となるため、「インスタンスプロパティ」としてオブジェクト経由で参照することはできない
 |
 +---  A::$p  ◯「クラスアクセス」インスタンスプロパティ
 |
 +---  A::$s  ◯「クラスアクセス」クラスプロパティ


メンバへのアクセス(メソッド)


class A
{
 public $p();
 public static $s();
}
$a = new A();
メンバへのアクセス(メソッド)  ※メソッド内の記述によっては下記と異なる挙動となる
 |
 +---  $a->p()  ◯「オブジェクト(インスタンスメソッド)経由アクセス」
 |
 +---  $a->s()  △「オブジェクト(クラスメソッド)経由アクセス」  ※可読性の観点から、クラス関数へはアロー演算子でアクセスしない方がよい
 |
 +---  A::p()  △「クラスアクセス(インスタンスメソッド経由)」  ※static でないメソッドを静的呼出ししているので、限りなくまちがいに近い
 |
 +---  A::s()  ◯「クラスアクセス(クラスメソッド経由)」


詳細

 閲覧数:370 投稿日:2017-02-19 更新日:2017-02-23 

一覧表



・可読性を考慮すると、避けた方が無難

一覧表              
メンバの種類 インスタンス経由アクセス「->」 クラス経由アクセス「::」
インスタンスプロパティ
クラスプロパティ ×
インスタンスメソッド △(staticでないメソッドを静的呼出し)
クラスメソッド
クラスメソッド
・staticメソッド内で「$this」使用不可
/*
* 値が異なったら、順位と値を更新するメソッド
* ランキング出力する際に使用
* @param  string $value 順位の基準となる値
* @return int    $rank 順位
*/
class Samerank
{
 public static $rank     = 0; //初期値(実際は最初必ず繰り上がるはずなので「1」小さい)
 public static $lastValue = null;
 
 public static function rankUpdate($value){
   if (Samerank::$lastValue !== $value) {//異なったら
     Samerank::$rank++;                  //順位を更新
     Samerank::$lastValue = $value;      //前のレコードの値を更新
   }
   return Samerank::$rank;
 }
}











メンバへアクセスする方法

 閲覧数:399 投稿日:2017-02-23 更新日:2018-01-18 

アクセス経路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";
?>






▼クラス継承時の注意事項

子クラスで親クラスと同名のプロパティを再定義する場合も、メソッドをオーバーライドする場合も、「クラスメンバ」だったものを「インスタンスメンバ」にしたり、「インスタンスメンバ」だったものを「クラスメンバ」に変更することは出来ない。
また、“「パブリック」な「スタティックプロパティ」”に関して、何れの場合も(子クラスで「スタティック」宣言したとしても)子クラスで再定義することができない。





メンバのアクセス制限

クラス定数

コメント投稿(ログインが必要)



類似度ページランキング
順位 ページタイトル抜粋
1 static修飾子 89
2 final修飾子 59
3 switch文 50
4 isset 43
5 $this 43
6 setcookie関数 40
7 include_path 38
8 imagick 38
9 Doctrine 35
10 ob_start 35
11 spliceImageメソッド 33
12 session.hash_function 33
13 session_start() 33
14 session.gc_maxlifetime 32
15 register_globals 32
16 Generators 32
17 preg_match 32
18 define と const の違い 30
19 SessionHandler::gc 30
20 文字列型(string) 29
2024/4/26 13:57 更新
週間人気ページランキング / 4-19 → 4-25
順位 ページタイトル抜粋 アクセス数
1 Parse error: syntax error, unexpected 'public' (T_PUBLIC) | Parse error(エラーメッセージ) 16
2 ブラウザを閉じたらセッションデータはどうなるの? | セッション 11
3 PHPで定数を定義する方法は2種類ある / 配列定数の定義 7
4 コード例 … 「例外処理」はネストすることができる 6
4 curl で Cookie を使用する 6
5 Warning: strlen() expects parameter 1 to be string, array given in ○○.php on line △△ | Warning(エラーメッセージ) 5
6 ブラウザを閉じたらセッションデータはどうなるの? | セッション 4
6 Fatal error: Access level to ▲::$△ must be protected (as in class ●) or weaker | Fatal error(エラーメッセージ) 4
7 Fatal error: Call to undefined method MDB2_Error::execute() in ○○ on line △△ | Fatal error(エラーメッセージ) 3
7 Fatal error: Uncaught Error: Class 'Mecab_Tagger' not found in /var/www/★★.php:☆☆ | Fatal error(エラーメッセージ) 3
7 Warning: include() [function.include]: Failed opening '**.php' for inclusion (in | Warning(エラーメッセージ) 3
7 型の種類 | 型 3
7 or(||) | 演算子 3
7 セッション名 | セッション 3
7 セッション管理が必要な理由は、HTTPプロトコルには状態を保持する機能がないため | セッション 3
7 ( ! ) Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined | Fatal error(エラーメッセージ) 3
7 Composer | 依存関係マネージャ 3
8 Cookie / Cookieとは? / Cookie仕様 2
8 セッションCookie | クッキー 2
8 Fatal error: Uncaught Wrench\Exception\HandshakeException: No accept header receieved on handshake response in ★★★ headless-chromium-php/vendor/wrench/wrench/lib/Wrench/Protocol/Protocol.php | エラーメッセージ 2
2024/4/26 1:02 更新