zoukankan      html  css  js  c++  java
  • php中self,this, parent 详解

    1、前言

    self,this,parent 这三个关键字在 类的使用中可谓屡见不鲜,那么这三个关键字又有什么区别;
    从字面意思理解:

    • this  是指向当前类(就近原则,离谁近跟谁)
    • self  是指向当前类(一般是静态变量,静态方法用,指本身)
    • parent是指向父类(php是单继承,父类也就只有一个)

    2、this 关键字

    测试类如下:

    <?php
    declare (strict_types = 1);
    class A 
    {
        public $name;
        function setName(string $name) 
        {
            $this->name = $name;
        }
        function getName()
        {
            var_dump($this->name);
        }
    }
    
    class B extends A
    {    
        //这里B继承A但是不做任何操作,
        //B也既有A的方法和属性
    }

    2.1、所以只对A类赋值,不对B类进行任何操作

    //this 指向当前对象
    $A = new A();
    $A->setName('I am A;');// 此方法的 $this 指向 A类,所以对 A类属性赋值
    
    $B = new B();
    
    echo $A->getName();
    echo '<br/>';
    echo $B->getName();

    输出结果:

    2.2、A、B类同时操作

    $A = new A();
    $A->setName('I am A;');// 此方法的 $this 指向 A类,所以对 A类属性赋值
    
    $B = new B();
    $B->setName('I am B;');//此方法的 $this 指向 B类, 所以对B类属性(继承A)赋值
    
    echo $A->getName();
    echo '<br/>';
    echo $B->getName();

    输出结果:

    2.3、结论

    A类 的赋值始终没有影响到 B类 的值;所以 $this 的操作只影响了当前类,不会影响了 类的继承;

    3、self 关键字

    首先:需要明确一点  self是指向类本身,self 跟 任何已经实例化的对象 没有任何关系

    测试类如下:

    <?php 
    declare (strict_types = 1);
    class A 
    {
        static public $name;
        function setName(string $name) 
        {
            self::$name = $name;
        }
        function getName()
        {
            var_dump(self::$name);
        }
    }
    class B extends A
    {    
        //这里B继承A但是不做任何操作,
        //B也既有A的方法和属性
    }

    3.1、 A类进行操作

    // B类的属性和方法来自 A类, self 此时指向 A类
    $A = new A();
    $A->setName('I am A;');// 此方法的 self 指向类本身,所以对 A 类的赋值,会影响到 B类
    
    $B = new B();
    
    echo $A->getName();
    echo '<br/>';
    echo $B->getName();

    输出结果:

    3.2、A类,B类同时操作

    //B类的属性和方法来自 A类, self 此时指向 A类
    $A = new A();
    $A->setName('I am A;');// 此方法的 self 指向 A类,所以对 A 类的赋值,会影响到 B类
    
    $B = new B();
    $B->setName('I am B;');// 此方法的 self 指向 A类,所以对 B 类的赋值,会影响到 A类
    
    echo $A->getName();
    echo '<br/>';
    echo $B->getName();

    输出结果:

    3.3、 B类重写 A类全部的方法和属性

    <?php 
    declare (strict_types = 1);
    class A 
    {
        static public $name;
        function setName(string $name) 
        {
            self::$name = $name;
        }
        function getName()
        {
            var_dump(self::$name);
        }
    }
    
    class B extends A
    {    
        //现在 B类拥有了自己的方法和属性
        static public $name;
        function setName(string $name) 
        {
            self::$name = $name;
        }
        function getName()
        {
            var_dump(self::$name);
        }
    }
    //B类重写了A类所有的方法和属性,所以 self(A) 指向 A类, self(B)指向 B类,
    $A = new A();
    $A->setName('I am A;');// 此方法的 self 指向 A类,所以对 A 类的赋值,不会影响到 B类
    
    $B = new B();
    $B->setName('I am B;');// 此方法的 self 指向 B类,所以对 B 类的赋值,不会影响到 A类
    
    echo $A->getName();
    echo '<br/>';
    echo $B->getName();
    输出结果:

    3.4、B类重新 A类 部分方法和属性

    <?php 
    declare (strict_types = 1);
    class A 
    {
        static public $name;
        function setName(string $name) 
        {
            self::$name = $name;
        }
        function getName()
        {
            var_dump(self::$name);
        }
    }
    
    class B extends A
    {    
        //现在 B类拥有了部分自己的方法和属性
        static public $name;
        function setName(string $name) 
        {
            self::$name = $name;
        }
    
    }
    // getName 的方法 继承来自 A类,所以 getName 中的 self指向 A类
    $A = new A();
    $A->setName('I am A;');// 此方法的 self 指向 A类,所以对 A 类的赋值,不会影响到 B类
    
    $B = new B();
    $B->setName('I am B;');// 此方法的 self 指向 B类,所以对 B 类的赋值,不会影响到 A类
    
    echo $A->getName();// 此方法的 self 指向 A类
    echo '<br/>';
    echo $B->getName();// 此方法的 self 指向 A类

    结果输出:

    3.5、结论

    从上面三组测试,不难看出,前两个例子,$name 属性只有 A类有, B类虽然继承了(还不是自己的),所以 self::$name 无论条件都指向了 A类,导致结果都一样,而第三个例子,当赋予了 B类自己的属性和方法了(重新了A类,self 就跟 A类没有任何关系了,指向了 B类),而第四个例子则看出,B 类的 getName 方法继承了A类,所以self 指向了A类。

    结语:self 指向类本身(他跟谁实例化他没关系,值关系到他属于那个类)

    4、parent 关键字

    首先:需要明确

    1. php 是单继承,父类永远只有一个
    2. parent 只能调用方法,不能调用属性
    3. parent 不会改变this指向

    4.1、调用父类带this的方法

    <?php 
    declare (strict_types = 1);
    class A 
    {
        public $name;
        function setName(string $name) 
        {
            $this->name = $name;
        }
        function getName()
        {
            var_dump($this->name);
        }
    }
    
    class B extends A
    {    
        function getName()
        {
            var_dump($this->name);
        }
        function getNameParent() 
        {
            parent::getName();
        }
    
    }
    
    $A = new A();
    $A->setName('I am A;');
    
    $B = new B();
    echo $A->getName();
    echo '<br/>';
    echo $B->getName();
    echo '<br/>';
    echo $B->getNameParent();//调用 A类的方法,当其中的 $this 还是指向 B类(就近(姑且这样理解))

    输出结果:

    4.2、当 A 类的方法是固定输出时

    <?php 
    declare (strict_types = 1);
    class A 
    {
        public $name;
        function setName(string $name) 
        {
            $this->name = $name;
        }
        function getName()
        {
            // var_dump($this->name);
            echo '欢迎使用 A类方法';
        }
    }
    
    class B extends A
    {    
        function getName()
        {
            echo '欢迎使用 B类方法';
        }
        function getNameParent() 
        {
            parent::getName();
        }
    
    }
    
    $A = new A();
    $A->setName('I am A;');
    
    $B = new B();
    echo $A->getName();
    echo '<br/>';
    echo $B->getName();
    echo '<br/>';
    echo $B->getNameParent();//调用 A类的方法,当其中的 $this 还是指向 B类(就近(姑且这样理解))

    输出结果:

    4.3、结语

    parent 指向 父类,但是不能改变 父类方法中 this 的指向, 而且只能访问 (public 和 protected ),对于private 会报错

    5、总结

    • this  是指向当前类(就近原则,离谁近跟谁)
    • self  是指向当前类(一般是静态变量,静态方法用,指本身)
    • parent是指向父类(php是单继承,父类也就只有一个)

    基本上我所了解就这么多,肯定有理解错误之处,请高手指出!

  • 相关阅读:
    从属性文件中读取配置
    Page Object Manager
    在Selenium中使用JavaScriptExecutor处理Ajax调用?
    wait
    常用操作
    Selenium收藏官方网址
    PageObject样例
    解决办法-错误:Access denied for user 'root'@'localhost'
    Struts2中的OGNL详解
    用C++,调用浏览器打开一个网页
  • 原文地址:https://www.cnblogs.com/ImCehnyx/p/7853815.html
Copyright © 2011-2022 走看看