昨天我在写PHP程序的时候,无心发如今PHP的::操做符很是强大,不单单是只用在访问parent,sel,静态成员属性、常量上面,其实他的功能强大了去了
。php
这个符号在PHP中实际上叫作范围解析符,这是PHP官方的解释php.net/manual/zh/language.oop5.paamayim-nekudotayim.php。可是官方中文部分只是简单的介绍了
访问parent,sel,静态成员属性、常量的做用,而下面英文部分,可能因为我们这些吊死对英文很差的缘故,就没看下去了,实现上,下面还有一个强大的特性,咱们你们都没看到。
什么叫范围操做符呢,可能不少人都没有认真的去分析过,这几个字,根据我这两年的编程的理解,我以为应该是定义了类中的成员属性和成员方法的所在范围,感受有点相似命名空间的感受。
而self::method();其实指的就是调用当前范围里的method方法,那parent天然指的就是父类所在范围,这就是为何,咱们在子类中 覆盖父类的方法,咱们仍然能够用parent::method()访问的缘由。你们还要注意一点,self永远指向的是其实声明位置所在类自己和而 parent永远指向的是声明位置所在类的父类,不会受继承上下文的影响而改变。
前面讲的这些可能你们有些人已经知道了,上面说过::在PHP中叫范围解析操做符,上面我说过了既然,parent和self都能指向一个类范围的代名词,那试想下,咱们能不能用类名指向某个范围呢,答案固然是能够的。咱们能够这样html
你们确定又疑惑这跟多继承有什么关系呢,别急,心急吃不了热豆腐的!!!!!
其实这个范围操做符还有一个很大的特性,就是当在类外部调用一个非静态公共方法时,方法内部的$this指针会指向他当前运行所在对象自己(宿主对象), 当一个类实例化时,方法里面$this永远指向的实例化后的对象自己,为何呢,由于这个方法是被这个对象调用执行的,因此这个对象就是他的宿主对象。而 刚才咱们直接在全局调中调用这个方法时,因为这个方法运行时不在任何对象中,因此不存在任何宿主对象,因此若是在方法里面写$this的话会报致命错误。 那怎么样才能拥有宿主对象,而后直接调用。仔细看我刚才讲的同窗可能注意到,我刚才说过"由于这个方法是被这个对象调用执行的,因此这个对象就是他的宿主 对象"。因此理论上说,咱们只要改变执行这个方法的所在环境,就能够改变他的宿主对象。下面咱们来实验下
class a{ public function say_name(){ echo 'my name is'.$this->name; } } class b{ public $name='xbs530'; public function run(){ a::say_name(); } } $o=new b; $o->run(); 你们猜会输出什么。。。。。。。 你们能够动手作一下试验。。。。。 因为a::say_name()是被对象$o调用的,因此方法里面的$this天然指向了对象$o。很神奇吧。。。。 这个我以前发的那个PHP范围解析操做符中都有讲,好了基础就讲到这里,下面直接上多继承的代码了,欢迎吐槽。。。。。 /* 多继承基类 注:要想实现类多继承,必需首先继承此基类 */ class multi_extends{ public function __construct(){ $this->_init_extends(); } protected function _init_extends(){ if(property_exists($this,'_extends')) { $extends=&$this->_extends; foreach($extends as $class) { $this->_extends($class); } } } public function _extends($class_name){ //分析目标 $ref = new ReflectionClass($class_name); //继承公共属性 $property_list=$ref->getProperties(ReflectionProperty::IS_PUBLIC); foreach($property_list as $property) { $property_name=$property->name; $property_value=$property->getValue(new $class_name); if($property_name==='_extends') { foreach($property_value as $c) { $this->_extends[]=$c; } }else{ if(!property_exists($this,$property_name)) { $this->{$property->name}=$property_value; } } } //继承公共方法 $method_list=$ref->getMethods(ReflectionMethod::IS_PUBLIC); foreach($method_list as $method) { $this->_extends_method[$method->name]=$method->class; } } function __call($m,$a){ if($c=$this->_extends_method[$m]) { eval("$c::$m(".'$a'.");"); } } } header('content-type:text/html;charset=utf-8'); class a{ public $a=5; public function say_name(){ echo '我叫'.$this->name.'<br>'; } } class b{ function say_age(){ echo '我今年'.$this->age.'岁<br>'; } } class c extends multi_extends{ public $_extends=array('a','b'); public function say_hellow(){ echo 'hellow '.$this->name.'<br>'; } } class d{ function say_goodbye(){ echo 'goodbye '.$this->name.'<br>'; } } class persion extends multi_extends{ public $_extends=array('c','d'); public $name="熊宝山"; public $age="20"; } //执行继承后的方法 $o=new persion(); $o->say_name(); $o->say_age(); $o->say_hellow(); $o->say_goodbye();