PHP類と対象の全解析(二)


目次
PHP類と対象の全解析(一)
PHP類と対象の全解析(二)
PHP類と対象の全解析(三)
7.Staticキーワード
クラスメンバーまたはメソッドがstaticであることを宣言すると、クラスをインスタンス化せずに直接アクセスできます.1つのオブジェクトから静的メンバーにアクセスできません(静的メソッドを除く).
静的メンバーはクラスに属し、オブジェクトインスタンスには属しませんが、クラスのオブジェクトインスタンスは共有できます.まとめ:
クラス内で静的メンバー属性またはメソッドにアクセスするには、self::($記号なし)を使用します.たとえば、self::$country//クラス内で静的メンバー属性self::myCountry()を使用して、子クラスで親静的メンバー属性またはメソッドにアクセスします.parent:($記号なし)を使用します.たとえば、parent:$country parent::myCountry()外部アクセス静的メンバー属性とメソッドはクラス名/サブクラス名:::Person:$country Person::myCountry()Studio::$countryただし静的メソッドは通常のオブジェクトでアクセスできます
    <?php  
      
    Class Person{  
        //           
        public static $country = "  ";  
        //           
        public static function myCountry() {  
            //             
            echo "  ".self::$country." <br />";  
        }  
    }  
    class Student extends Person {  
        function study() {  
            echo "  ". parent::$country." <br />";  
        }  
    }  
    //          
    echo Person::$country."<br />";     //
    $p1 = new Person();  
    //echo $p1->country;            //       
    //           
    Person::myCountry();            //   :       
    //             :  
    $p1->myCountry();  
      
    //             
    echo Student::$country."<br />";    //
    $t1 = new Student();  
    $t1->study();           //
      
    ?>  

---------------------------------------------------
8.抽象クラスPHP 5は抽象クラスと抽象メソッドをサポートする.
抽象クラスを直接インスタンス化することはできません.まず、その抽象クラスを継承してから、サブクラスをインスタンス化する必要があります.抽象クラスには少なくとも1つの抽象メソッドが含まれます.クラスメソッドが抽象的に宣言されると、特定の機能実装は含まれません.抽象クラスを継承する場合、サブクラスは抽象クラスのすべての抽象メソッドを実現しなければならない.また,これらの方法の可視性は抽象クラスと同様(またはより緩やか)でなければならない.抽象クラスの抽象メソッドがprotectedとして宣言されている場合、サブクラスで実装されるメソッドはprivateとして定義することなくprotectedまたはpublicとして宣言する必要があります.//抽象方法:abstract protected function getValue()例1
    abstract class AbstractClass{  
        //         
        abstract protected function getValue();  
        //       
        public function printOut(){  
            print $this->getValue()."<br />";  
        }  
    }  
    class ConcreteClass extends AbstractClass{  
        protected function getValue(){  
            return "abstract ";//         
        }  
    }  
      
    $class1 = new ConcreteClass;  
    $class1->printOut();  

例2
    abstract class AbstractClass  
    {  
     //               
        abstract protected function getValue();  
        abstract protected function prefixValue($prefix);  
      
        //     (     )  
        public function printOut() {  
            print $this->getValue() . "
"; } } class ConcreteClass1 extends AbstractClass { protected function getValue() { return "ConcreteClass1"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass1"; } } class ConcreteClass2 extends AbstractClass { public function getValue() { return "ConcreteClass2"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass2"; } } $class1 = new ConcreteClass1; $class1->printOut(); echo $class1->prefixValue('FOO_') ."
"; $class2 = new ConcreteClass2; $class2->printOut(); echo $class2->prefixValue('FOO_') ."
";

/**抽象クラスは直接インスタンス化できません.まず抽象クラスを継承してから、サブクラスをインスタンス化する必要があります.抽象クラスには少なくとも1つの抽象メソッドが含まれます.クラスメソッドが抽象的に宣言されると、特定の機能実装は含まれません.抽象クラスを継承する場合、サブクラスは抽象クラスのすべての抽象メソッドを実現しなければならない.また,これらの方法の可視性は抽象クラスと同様(またはより緩やか)でなければならない.抽象クラスの抽象メソッドがprotectedとして宣言されている場合、サブクラスで実装されるメソッドはprivateとして定義することなくprotectedまたはpublicとして宣言する必要があります. *  */
    class Person {  
        public $name;  
        public $age;  
      
        function say() {  
            echo "my name is:".$this->name."<br />";  
        echo "my age is:".$this->age;  
        }  
    }  

//クラスの継承
    class Student extends Person {  
        var $school;    //           
          
        function study() {  
            echo "my name is:".$this->name."<br />";  
            echo "my shool is:".$this->school;  
        }         
    }  
      
    $t1 = new Student();  
    $t1->name = "zhangsan";  
    $t1->school = "beijindaxue";  
    $t1->study();  

---------------------------------------------------------------------
9.インタフェース
インタフェース定義:メソッドと定数値定義のセットはinterfaceによってインタフェースを定義します.標準クラスを定義するように、定義されていますが、定義されているすべてのメソッドは空です.インタフェースの特性:インタフェースで定義されたすべての方法はpublicインタフェースの実装である必要があります.1つのインタフェースはimplementsオペレータを使用することができ、クラスではインタフェースのすべての方法を実装する必要があります.そうしないとfatalエラーが報告されます.複数のインタフェースを実装する場合は、カンマを使用して複数のインタフェースの名前を区切ることができます.
抽象クラスとインタフェースの違い
インタフェースは特殊な抽象クラスであり,モデルの仕様と見なすこともできる.インタフェースと抽象クラスの違いは以下の通りです.
1.サブクラスimplementsインタフェースが1つの場合、インタフェース内のすべての方法(必要かどうかにかかわらず)を実装する必要があります.抽象クラスを継承する場合は、必要なメソッドを実装するだけです.2.インタフェースで定義されたメソッド名が変更された場合、このインタフェースを実装するすべてのサブクラスは、メソッド名を同期的に更新する必要がある.抽象クラスでメソッド名が変更されると,そのサブクラスに対応するメソッド名は影響を受けず,新しいメソッド(比較的古いメソッド実装)になる.3.抽象クラスは単一でのみ継承でき、1つのサブクラスが実装する機能が複数の親クラスから継承する必要がある場合は、インタフェースを使用する必要があります.インスタンス1://iTemplateインタフェースを宣言
nterface iTemplate  
{  
    public function setVariable($name, $var);  
    public function getHtml($template);  
}  

//実装コネクタ//以下の書き方が正しい
    class Template implements iTemplate  
    {  
        private $vars = array();  
        
        public function setVariable($name, $var)  
        {  
            $this->vars[$name] = $var;  
        }  
        
        public function getHtml($template)  
        {  
            foreach($this->vars as $name => $value) {  
                $template = str_replace('{' . $name . '}', $value, $template);  
            }  
       
            return $template;  
        }  
    }  

インスタンス2://インタフェースの定義
    interface User{  
         function getDiscount();  
         function getUserType();  
     }  

//VIPユーザーインタフェース実装
    class VipUser implements User{  
        // VIP         
        private $discount = 0.8;  
        function getDiscount() {  
            return $this->discount;  
        }  
        function getUserType() {  
            return "VIP user";  
        }  
    }  
    class Goods{  
        var $price = 100;  
        var $vc;  
        //   User       ,             
        function run(User $vc){  
            $this->vc = $vc;  
            $discount = $this->vc->getDiscount();  
            $usertype = $this->vc->getUserType();  
            echo $usertype."goods Price:".$this->price*$discount;  
        }  
    }  
      
    display ->run(new VipUser);    //             

-------------------------------------------------------------
10.重荷
定義:クラス内のメソッドは別のメソッド名と同じですが、パラメータが異なる場合はリロードを実行しますか?現在の環境で定義されていない属性またはメソッドが呼び出された場合、または現在の環境では表示されない属性またはメソッドが呼び出されます.ヒント:親定義メソッドでfinalキーワードが使用されている場合は、布団メソッドの上書きは許可されません.
親が上書きされたメソッドにアクセスするにはparent::記号を使用して、親が上書きされたメソッドまたはメンバーのプロパティにアクセスします://PPPリロードメソッド_call()
 __Call()(Method overloading)呼び出しメソッドが存在しない場合にエラーが発生しないように_コール()メソッドで回避します.このメソッドは、呼び出されたメソッドが存在しない場合に自動的に呼び出され、プログラムは実行されます.
文法://_call()メソッドリロード
    class Test{  
        public function __call($name,$args){  
         if($name== 'null' && count($args)==2 ){  
          $type='num';  
       foreach($args as $key => $val){  
           if(!(is_int($val) || is_float($val))){  
            $type= 'string';  
        }  
       }  
       $method=$name.ucfirst($type);  
       if(method_exists($this,$method),$args){  
           call_user_func_array(array($this,$method),$args);  
       }  
      }  
     }  
     public addNum($i,$j){  
         echo $i+$j;  
     }  
       
     public addString($i,$j){  
         echo $i.$j;  
     }  
    }  
    $test =new Test();  
    $test->add(3,4);  
    $test->add(3,'4');  
       

ケース:
    class MemberTest {  
            
        private $data = array();//              
        public $declared = 1;/**                  */  
        private $hidden = 2; /**               ,       */  
      
        public function __set($name, $value) {  
            echo "Setting '$name' to '$value'
"; $this->data[$name] = $value; } public function __get($name) { echo "Getting '$name'
"; if (array_key_exists($name, $this->data)) { return $this->data[$name]; } $trace = debug_backtrace(); trigger_error( 'Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_NOTICE); return null; } /** PHP 5.1.0 */ public function __isset($name) { echo "Is '$name' set?
"; return isset($this->data[$name]); } /** PHP 5.1.0 */ public function __unset($name) { echo "Unsetting '$name'
"; unset($this->data[$name]); } /** */ public function getHidden() { return $this->hidden; } } echo "<pre>
"; $obj = new MemberTest; $obj->a = 1; echo $obj->a . "

"; var_dump(isset($obj->a)); unset($obj->a); var_dump(isset($obj->a)); echo "
"; echo $obj->declared . "

"; echo "Let's experiment with the private property named 'hidden':
"; echo "Privates are visible inside the class, so __get() not used...
"; echo $obj->getHidden() . "
"; echo "Privates not visible outside of class, so __get() is used...
"; echo $obj->hidden . "
";

//属性リロード:_set(),__get(),__isset(),__unset()
    class Person{  
        private $data =array();  
        function __set($name,$value){  
         $this->data[$name]=$value;  
     }  
     function __get($name){  
         return $this->data[$name];  
     }  
    }  

-----------------------------------------------------------------------------------
11.オブジェクト反復
PHP 5は、配列を使用するように、foreachによってオブジェクト内の属性を巡回する反復オブジェクトの機能を提供する.
    class MyClass  
    {  
        public $var1 = 'value 1';  
        public $var2 = 'value 2';  
        public $var3 = 'value 3';  
      
        protected $protected = 'protected var';  
        private   $private   = 'private var';  
      
        function iterateVisible() {  
           echo "MyClass::iterateVisible:
"; foreach($this as $key => $value) { print "$key => $value
"; } } } $class = new MyClass(); foreach($class as $key => $value) { print "$key => $value
"; } echo "
"; $class->iterateVisible();

---------------------------------------------------------------------------
12.設計モード:工場モードと一例モード、観察者モード、コマンドチェーンモードと策略モード
 
コマンドチェーンモードは、ばらばらな結合トピックに基づいて、メッセージ、コマンド、リクエストを送信するか、プロセッサのセットを介して任意のコンテンツを送信します.各プロセッサは,要求を自分で処理できるか否かを判断する.可能であれば、リクエストが処理され、プロセスが停止します.他のプロセッサに影響を与えることなく、システムにプロセッサを追加または削除できます.
ファクトリモード定義:ファクトリモード(Factory)を使用すると、コード実行時にオブジェクトをインスタンス化できます.工場モデルと呼ばれるのは、「生産」対象を担当しているからです.ファクトリメソッドのパラメータは、生成するオブジェクトに対応するクラス名です.ファクトリモード構文:
    <?php  
    class Example  
    {  
        public static function factory($type)  
        {  
            if (include_once 'Drivers/' . $type . '.php') {  
                $classname = 'Driver_' . $type;  
                return new $classname;  
            } else {  
                throw new Exception ('Driver not found');  
            }  
        }  
    }  
    ?>   

工場モデルのケース:
    <?php  
    interface IUser{  
     function getName();  
    }  
    class User implements IUser{  
     public function __construct($id){}  
     public function getName(){  
         return "haha";  
     }  
    }  
    class UserFactory{  
        public static function Create($id){  
      return new User($id);  
     }  
    }  
    $uo =UserFactory::Create(1);  
    echo $uo->getName();  
      
    ?>  

単一の例は3つの要素を定義します:1、あるクラスには1つのインスタンスしかありません2、このインスタンスを自分で作成する必要があります3、このインスタンスの役割を自分でシステムに提供する必要があります:1、システムの中でいくつかの構成情報をグローバルに制御するために1つのクラスが必要な場合、単一の例のモードを使用すると便利に実現できます.2、単一の例のモードを使用して、大量のnew操作が資源を消費することを避けることができます()3 1つのページの要求の中で、デバッグを容易にすることができて、すべてのコードが1つのクラス(例えばデータベースの操作クラス)に集中するため、クラスの中でフックを設定することができて、ログを出力して、それによって至る所var_dump単一モード(Singleton)は、クラスに一意のオブジェクトを生成するために使用されます.最も一般的な場所はデータベース接続です.単一のインスタンスモードを使用してオブジェクトを生成すると、そのオブジェクトは他の多くのオブジェクトで使用できます.単体モードは我々が開発中によく使う設計モードであり、PHP 5のオブジェクト向けの特性を利用して、我々は簡単に単体モードの応用を構築することができ、以下は単体モードのPHPにおけるいくつかの実現方法である.
    class Stat{  
        static $instance = NULL;  
          
        static function getInstance(){  
            if(self::$instance == NULL){  
                self::$instance = new Stat();  
            }  
              
            return self::$instance;  
        }      
        private function __construct(){  
        }      
        private function __clone(){  
        }      
          
        function sayHi(){  
            return "The Class is saying hi to u ";  
        }  
    }  
      
      
    echo Stat::getInstance()->sayHi();   

これは、getInstanceメソッドで一意のクラスインスタンスを返す最も一般的な方法です.
ここの例を少し修正すると、単品を使いたいクラスを呼べば、一般的な方法が生まれます.
    class Teacher{  
        function sayHi(){  
            return "The teacher smiling and said 'Hello '";  
        }  
          
        static function getInstance(){  
            static $instance;  
              
            if(!isset($instance)){  
                $c = __CLASS__;  
                $instance = new $c;  
            }          
            return $instance;  
        }  
    }  
      
    echo Teacher::getInstance()->sayHi();   

最後にsingletonクラスを提供し、getInstanceメソッドを呼び出すことで、どのクラスにもインスタンスを生成できます.
    class singleton{  
        function getInstance($class){  
            static $instances = array();  
            if(!array_key_exists($class,$instances)){  
                $instances[$class] = &new $class;  
            }  
            $instance = $instances[$class];  
              
            return $instance;  
        }  
    }  
      
    class People{  
        function sayHi(){  
            return 'Hello i am a people?';  
        }  
    }  
      
    echo "<br />";  
    echo singleton::getInstance('People')->sayHi();   

この3つの方法により、単一のモードを簡単に適用することができ、工場モードと組み合わせることができれば、プログラミングをより合理的で効率的にすることができます.