ホームページ > バックエンド開発 > PHPチュートリアル > PHP クラスとオブジェクトの完全な分析 (2)

PHP クラスとオブジェクトの完全な分析 (2)

WBOY
リリース: 2016-06-23 13:42:36
オリジナル
793 人が閲覧しました

ディレクトリ

PHPクラスとオブジェクトの完全分析(1)

PHPクラスとオブジェクトの完全分析(2)

PHPクラスとオブジェクトの完全分析(3)

7.静的キーワード


の宣言クラス メンバー または、メソッドが静的である場合は、クラスをインスタンス化せずに直接アクセスできます。静的メンバー (静的メソッドを除く) には、オブジェクトを通じてアクセスできません。

静的メンバーはクラスに属し、どのオブジェクト インスタンスにも属しませんが、クラスのオブジェクト インスタンスは共有できます。
概要:

クラス内の静的メンバーのプロパティまたはメソッドにアクセスするには、次のように self:: ($ 記号なし) を使用します。
self:: $country //クラス内の静的メンバーのプロパティにアクセスします
self:: my Country( )
in サブクラスが親クラスの静的メンバーのプロパティまたはメソッドにアクセスする場合は、parent:: ($ 記号なし) を使用します。次のようになります。
parent:: $country
parent:: my Country()
static への外部アクセスメンバーのプロパティとメソッドはクラス名/サブクラス Name:: です。例:
Person::$country
Person::my Country()
Student::$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. 抽象クラス PHP5 抽象クラスと抽象メソッドをサポートします。


抽象クラスは直接インスタンス化できません。最初に抽象クラスを継承してから、サブクラスをインスタンス化する必要があります。
抽象クラスには、少なくとも 1 つの抽象メソッドが含まれている必要があります。クラス メソッドが抽象として宣言されている場合、具体的な関数実装を含めることはできません。
抽象クラスを継承する場合、サブクラスは抽象クラス内のすべての抽象メソッドを実装する必要があります。
さらに、これらのメソッドの可視性は抽象クラスと同じ (またはより緩和された) 必要があります。
抽象クラス内の抽象メソッドが保護されていると宣言されている場合、サブクラスに実装されているメソッドは保護またはパブリックとして宣言する必要があり、プライベートとして定義することはできません。
//抽象メソッド: 抽象保護関数 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() . "\n";          }      }            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_') ."\n";            $class2 = new ConcreteClass2;      $class2->printOut();      echo $class2->prefixValue('FOO_') ."\n";  
ログイン後にコピー

/*
* 抽象クラスを直接インスタンス化することはできません。最初に抽象クラスを継承する必要があります。インスタンス化するサブクラス。
抽象クラスには、少なくとも 1 つの抽象メソッドが含まれている必要があります。クラス メソッドが抽象として宣言されている場合、具体的な関数実装を含めることはできません。
抽象クラスを継承する場合、サブクラスは抽象クラス内のすべての抽象メソッドを実装する必要があります。
さらに、これらのメソッドの可視性は抽象クラスと同じ (またはより緩和された) 必要があります。
抽象クラス内の抽象メソッドが保護されていると宣言されている場合、サブクラスに実装されているメソッドは保護またはパブリックとして宣言する必要があり、プライベートとして定義することはできません。
*
*/

    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. インターフェース


インターフェース定義 : メソッドと定数値の定義のコレクション
インターフェイスを介してインターフェイスを定義することは、標準クラスを定義するのと同じですが、その中で定義されているメソッドはすべて空です。

インターフェースの特性: インターフェースで定義されたすべてのメソッドは public である必要があります。

インターフェースの実装: インターフェースは、implements 演算子を使用でき、クラスはインターフェース内のすべてのメソッドを実装する必要があります。そうしないと、致命的なエラーが報告されます。複数のインターフェイスを実装する場合は、カンマを使用して複数のインターフェイスの名前を区切ることができます。

抽象クラスとインターフェースの違い

インターフェースは特別な抽象クラスであり、モデルの仕様とみなすこともできます。インターフェイスと抽象クラスの一般的な違いは次のとおりです。

1. サブクラスがインターフェイスを実装する場合、抽象クラスを継承する場合はインターフェイス内のすべてのメソッドを実装する必要があります。必要なメソッドを実装します。
2. インターフェイスで定義されたメソッド名が変更された場合、このインターフェイスを実装するすべてのサブクラスはメソッド名を同期的に更新する必要があり、抽象クラスでメソッド名が変更された場合でも、そのサブクラスの対応するメソッド名は影響を受けません。 、ただし、(古いメソッドの実装と比較して) 新しいメソッドになるだけです。
3. 抽象クラスは単独でのみ継承できます。サブクラスが複数の親クラスから継承する必要がある関数を実装する必要がある場合は、インターフェイスを使用する必要があります。
例 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:
// インターフェイスを定義します

rrリー

//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:: 符号来访问父类被覆盖的方法或成员属性:
//PHP 重载方法 __call()

__call()(Method overloading)
为了避免当调用的方法不存在时产生错误,可以使用 __call() 方法来避免。该方法在调用的方法不存在时会自动调用,程序仍会继续执行下去。

语法:
// __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'\n";              $this->data[$name] = $value;          }                public function __get($name) {              echo "Getting '$name'\n";              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?\n";              return isset($this->data[$name]);          }                /**  PHP 5.1.0之后版本 */          public function __unset($name) {              echo "Unsetting '$name'\n";              unset($this->data[$name]);          }                /**  非魔术方法  */          public function getHidden() {              return $this->hidden;          }      }                  echo "<pre class="brush:php;toolbar:false">\n";            $obj = new MemberTest;            $obj->a = 1;      echo $obj->a . "\n\n";            var_dump(isset($obj->a));      unset($obj->a);      var_dump(isset($obj->a));      echo "\n";            echo $obj->declared . "\n\n";            echo "Let's experiment with the private property named 'hidden':\n";      echo "Privates are visible inside the class, so __get() not used...\n";      echo $obj->getHidden() . "\n";      echo "Privates not visible outside of class, so __get() is used...\n";      echo $obj->hidden . "\n";  
ログイン後にコピー

//属性重载:__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.对象迭代


PHP5提供了一种迭代(iteration)对象的功能,就像使用数组那样,可以通过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:\n";             foreach($this as $key => $value) {                 print "$key => $value\n";             }          }      }            $class = new MyClass();            foreach($class as $key => $value) {          print "$key => $value\n";      }      echo "\n";                  $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();            ?>  
ログイン後にコピー

单例
定义三要素:1,某个类只能有一个实例 2,必须自行创建这个实例 3,必须自行向系统提供这个实例

作用: 1,如果系统中需要有一个类来全局控制某些配置信息,那么使用单例模式可以很方便的实现。
2,使用单例模式,可以避免大量的new操作消耗资源()
3在一个页面请求中,便于调试,因为所有的代码都集中在一个类中(如数据库操作类) 可以在类中设置钩子,输出日志,从而避免到处都是var_dump

单例模式(Singleton)用于为一个类生成一个唯一的对象。最常用的地方是数据库连接。 使用单例模式生成一个对象后,该对象可以被其它众多对象所使用。
单件模式是我们在开发中经常用到的一种设计模式,利用PHP5面向对象的特性,我们可以很容易的构建单件模式的应用,下面是单件模式在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();   
ログイン後にコピー

通过这三种方法,我们可以很容易的应用单件模式,如果能够结合工厂模式,将使我们的编程变得更有条理和效率。
---------------------------------------------------------------------------------------

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート