如何理解PHP中类的静态属性的继承关系

2022-04-25 奥古斯宏

比如在以下代码中,输出是什么样的呢?

<?php
class red{
    public static $name = "red";
    public $age = 10;
    public function get(){
        echo self::$name."\n";
        echo $this->age;
    }
}
class yello extends red {
    public static $name = "yello";
    public $age = 20;
    public function show(){
        echo self::$name ."\n". parent::$name."\n";
        echo $this->age."\n";
        echo parent::get();
    }
}
$s = new yello();
$s ->show();

?>

以上代码输出的内容时:

yello,red,20,red,20


网络上有很多关于介绍对象和类的文章,即便这些文章不是介绍PHP的,也可以看看,类和对象的概念在所有编程语言中是一样的。这里我尽量简单地介绍一下,如果有不合适的地方欢迎指出。

可以这样理解,类是设计图,对象是产品。

类的继承,就是设计图的版本修改,子类是最新的版本。

当实例化一个类时,从“设计图”生成“产品”,此时产品的属性(非静态属性),是按照最新的设计图上的内容生产的,比如旧的设计图上age是10,新的设计图上age是20,所以产品上的age就是20 。设计图里可能有很多个版本的age,但是产品只有一个age,就是最新的设计图上的age。

版权声明:本文由phpreturn.com(PHP武器库官网)原创和首发,所有权利归phpreturn(PHP武器库)所有,本站允许任何形式的转载/引用文章,但必须同时注明出处。

那怎么理解静态属性呢?你可以这么认为,生产“产品”时,不会将静态属性“安装到”产品上,静态属性只是一个设计图上的一个说明。可以在产品里访问设计图上的一个说明,这个完全讲得通。并且,一个产品可以有多个设计图,这个也完全讲得通。

这里要注意,在PHP中,访问静态属性有很多写法:

self::$name; // 内部调用当前所在类的静态属性
static::$name; // 内部调用,实例化后,访问实例化的那个类的静态属性
red::$name;  // 指名道姓的访问red类的静态属性,类的内部外部都可
yello::$name; // 指名道姓的访问yello类的静态属性,类的内部外部都可
$s::$name;  // 通过实例化的对象访问静态的属性,根据继承关系,访问到的是实例化的那个子类的属性

按照你的代码例子中:

有两个设计图:

  • red类
  • yello类

生产出了一个产品:

  • $s (通过yello实例化出来的)

实例化yello的时候,根据yello的设计图,生产了一个$s对象,对象上安装了age属性。至于name静态属性,并没有安装到这个产品上,而是产品的设计图。对象的age,只能访问到20,因为yello的设计图上是20 。 但是访问静态属性name的时候,根据不同的访问方式,会访问到不同的设计图。

版权声明:本文由phpreturn.com(PHP武器库官网)原创和首发,所有权利归phpreturn(PHP武器库)所有,本站允许任何形式的转载/引用文章,但必须同时注明出处。

比如:

  • 在类内部使用self::$name的方式,则表示访问当前设计图的name;
  • 在类内部使用static::$name的方式,则表示访问实际生产产品所使用的那个设计图的name;
  • 无论类的内部或外部,使用red::$name,则总是会访问到red设计图上的name;
  • yellow::$name同理;
  • 通过实例化出的对象访问静态属性时,$s::$name,则表示访问这个产品所使用的那个设计图的name。

以上,是静态变量的用法

所以指向父类的非静态属性并没有被重写,静态属性不会被重写,只是不同的访问方式,对应的静态属性不一样。他就是设计图上的一个值。类本身就存在与内存中,这个值也就存在于内存中。

至于普通的属性(非静态属性),本身不存在,他只是设计图上的一个设计,只有实例化成对象之后(生产成产品),内存中就多了一个对象,这个属性才被安装到对象上。

评论
点击登录