【问题标题】:Why is not possible for a child class to inherit properties class that are set dynamically?为什么子类不能继承动态设置的属性类?
【发布时间】:2020-01-10 14:19:20
【问题描述】:

当属性被硬编码时,属性的继承是可能的。见下文:

class ParentObj {   

    protected $familyName = 'Lincoln';   

}   

class ChildObj extends ParentObj {   

    public function __construct() {   
        var_dump($this->familyName);  
    }   
}   

$childObj = new ChildObj();   

// OUTPUT 
string 'Lincoln'

当属性是动态的时,不能继承属性。见下文:

class ParentObj {   

    protected $familyName; 

    public function setFamilyName($familyName){  
        $this->familyName = $familyName;  
    } 

}   

class ChildObj extends ParentObj {   

    public function __construct() {   
        var_dump($this->familyName);  
    }   
}   

$familyName = 'Lincoln';  
$parentObj = new ParentObj();  
$parentObj->setFamilyName($familyName); 

$childObj = new ChildObj(); 

// OUTPUT
null

那么问题来了:为什么子类不能继承动态设置的属性类?

【问题讨论】:

  • 你误解了类和类实例的区别

标签: php oop object


【解决方案1】:

子类从父类继承它的初始状态。它不继承自具体的父对象实例。

在您的第一个示例中,“Lincoln”适用于 所有 ParentObject 创建的实例。在您的第二个示例中,它仅适用于具体的$parentObj。您正在将其专门设置为该实例。

请参阅我的回答 What is a class in PHP? 以获得更详尽的解释。

【讨论】:

  • 简短但甜蜜,你能告诉我是否可以从具体的父对象实例继承吗?
  • @Julian 您可以将其设为静态,如页面其他位置所示,但这将使其成为您创建的每个子节点的值,并为每个现有子实例更改它。如果这不是您想要的,您可以在父级上有一个方法来创建子级,然后将其自己的状态设置为子级。然后你会做类似$parentObj->createChild();的事情。
【解决方案2】:

如果您想从所有实例(对象)中访问$familyName 的值,您可以将$familyName 定义为静态,即创建一个全局类变量。

例如

<?php

class ParentObj {

    protected static $familyName;

    public function setFamilyName($familyName){
        self::$familyName = $familyName;
    }

}

class ChildObj extends ParentObj {

    public function __construct() {
        var_dump(self::$familyName);
    }
}

$familyName = 'Lincoln';
$parentObj = new ParentObj();
$parentObj->setFamilyName($familyName);
$childObj = new ChildObj(); // Output: Lincoln

$familyName = 'Lee';
$parentObj->setFamilyName($familyName);
$childObj = new ChildObj(); // Output: Lee

注意事项: $familyName 现在是一个全局变量,并且会针对该对象的所有实例进行更改。如果您更改脚本中的值,这可能会导致意外结果。全局变量通常被认为是个坏主意。

【讨论】:

  • 请记住,$familyName 现在是一个全局变量,并且会针对该对象的所有实例进行更改。如果您更改脚本中的值,这可能会导致意外结果。全局变量通常被认为是一个坏主意。
  • @jibsteroos 那么静态属性是实现共享内存的一种方式吗?
  • 基本上,静态属性可用于存储与特定类相关的持久值,该值不属于该类的实例(对象)。查看它们的一种方法是 global variables 用于类。因此,您不必创建类(对象)的实例来访问该属性。有关静态属性的更多信息,请查看this
猜你喜欢
  • 2010-10-20
  • 2015-07-06
  • 1970-01-01
  • 1970-01-01
  • 2019-03-09
  • 1970-01-01
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
相关资源
最近更新 更多