美文网首页程序员PHP经验分享
php 不符合常理的static self parent

php 不符合常理的static self parent

作者: 宋大肿 | 来源:发表于2018-01-10 21:55 被阅读54次

    没有废话 ,我想直接抛出问题。

    一、php继承问题

    上代码。

    
    class father{
        public function __construct(){
          echo "类father";
    }
    }
    class child extends father{
        public function __construct(){
          echo "类child";
    }
    }
    
    $p=new child();
    

    输出结果: 类child

    如果我们接触过纯面向对象的语言 :c#/java;
    按照他们的语法,以上例子将会输出 :
    类father
    类child

    当我们在new子类对象的时候,编译器应该会实例化它的父类,以此来产生一个继承链条,我们看到表面上php仅仅实例化了一个子类对象,这并不科学,也是后续问题产生的一个根本原因:php到底存不存在继承链?

    二、static 、self、parent这些关键字

    class father{
    public $a="father";
    public function __construct(){
          echo "类father";
    }
    public function Say(){
          echo __CLASS__."say";
    }
    }
    class child{
        public function __construct(){
            parent::construct();
        self::Say();
    static::Say();  
    
    $this->a;
          echo "类 child";
    }
    }
    $childs=new child();
    
    

    如果php不存在继承链,那么以上程序将报错。
    所以php是存在继承链。

    并且以上存在一些语法规则,子类可以通过self或者是static等关键字,去调用父类中可供调用的方法,和$this类似。

    那么我们是不是就可以理解成:self::或者是static::语法,指向了一个father类的实力对象? 要不然成员方法怎么调用?

    但是奇怪的是:static::/self:: 不能调用属性字段(非静态),parent::也是如此。

    这个就尴尬了,凭什么非静态的方法能调用,字段属性就不行?

    那么应该推翻self::/static::是对象的引用,他们应该是类层面上的引用。

    产生了矛盾。

    凭什么能调用成员的方法,却无法调用成员属性?

    答案存在于内存分布上面:
    我们知道内存分为4部分:

    1. 静态数据区
    2. 代码区
      实例化对象的时候,将属性都存放到了堆里面。方法存在于代码区,调用的时候,根据类指针来寻找存放地址,进行调用。

    我们可以大体了解到,属性可以在代码运行时动态改变值。方法,一旦我们定义好之后,代码编译完成方法体就很难改变,所以在内存中如此存放,更加节约空间。

    所以,不管是static 还是self、parent都是指向类指针,可以调用静态变量,以及方法列表。
    $this真正指向本对象。

    相关文章

      网友评论

        本文标题:php 不符合常理的static self parent

        本文链接:https://www.haomeiwen.com/subject/libzixtx.html