【问题标题】:Parent class property set by parent method blank when accessing from child method从子方法访问时父方法设置的父类属性为空
【发布时间】:2011-07-30 22:11:55
【问题描述】:

我无法理解为什么我可以从我的父类访问一个属性,但它是 NULL,即使它已经由父类设置(并且没有被故意重置)。我认为这可能是因为该属性是由私有方法设置的,但是当我更改为 public 时没有区别。这是一个彻底简化的示例:

class TheParent
{

    protected $_parent_property;

    function __construct()
    {}

    private function parent_method($property);
    {
        $this->_parent_property = $property;
            $call = new TheChild;
            $call->child_method();
    }
}

class TheChild extends TheParent
{ 
    function __construct()
    {
        parent::construct();
    }

    public function child_method();
    {
        echo $this->_parent_property;
            exit;
    }
}

$test = new TheParent;
$test->parent_method('test');

我通过在子由父构造即new TheChild($this->_parent_property) 时将父属性传递给子来解决此问题,但我仍然不明白为什么从子访问时 $this->_parent_property 设置为 NULL在我原来的例子中。

我确实知道,如果我从父构造函数中设置此属性,我就可以正常访问它。我试图理解为什么由父方法设置并可由其他父方法访问的属性不能从扩展父级的子类访问。

谁能解释一下?谢谢!

【问题讨论】:

    标签: php oop inheritance properties


    【解决方案1】:

    问题是您正在创建一个未设置变量的新实例。该属性绑定到一个特定的实例,因此您正在创建父级的一个实例,然后从父级创建另一个子级实例,其中包括创建新父级将包含的所有内容,包括$_parent_property。当您读取子项中的值时,您正在读取的是新创建的父项的值,而不是您之前创建的值。

    实际上,你这样做:

    A = new TheParent()
    A->_parent_property = 'test'
    

    调用: B = new TheChild() 在幕后,这是new TheParent()

    Print B->_parent_property(未初始化)

    考虑这个将产生您预期结果的类似示例:

    class TheParent
    {
    
        protected $_parent_property;
    
        function __construct()
        {
            parent_method();
        }
    
        private function parent_method();
        {
            $this->_parent_property = 'test';
        }
    }
    
    class TheChild extends TheParent
    { 
        function __construct()
        {
            parent::construct();
        }
    
        public function child_method();
        {
            echo $this->_parent_property;
            exit;
        }
    }
    
    $child = new TheChild();
    $child->child_method();
    

    在此示例中,TheParent 中的私有方法在 TheChild 创建的同一实例上调用,并设置底层实例变量。

    【讨论】:

    • 感谢您的回复,马克。我刚刚更新了我的示例以显示在调用父方法时我正在传递父属性的值。根据您的回答,我想如果不先将原始参数值传递给子类,就不可能将其保留在属性中?
    • @Calvin:你的关系是倒退的,TheChild 继承自 TheParent,如果你想要 TheChild 扩展 TheParent,你应该将 setter 方法暴露给 TheChild,或者删除继承关系并将TheParent 的实例传递给TheChild(或只是您需要的变量)
    • 它们被称为静态变量。为什么TheParent 实例化TheChild
    • @todda:静态变量与字段(有时称为属性)不同,这里所讨论的变量是字段,而不是静态字段。在我的示例中,TheChild 实例化了 TheParent,而不是相反,所以我不确定你在问什么。
    • @Mark 我现在明白了。我认为去除继承关系并传递父类的实例绝对是要走的路。谢谢你的帮助,伙计=)
    【解决方案2】:

    您对继承的工作原理有点错误的想法。

    TheParent 是一个类,TheChild 是一个基于TheParent 的类。 $test 现在是 TheParent 的一个实例。不知道在TheParent类的基础上还有另一个类TheChild

    您创建一个新实例$call,它的类型为TheChild。用另一个词来说,这是一个新的对象。它与$test 无关,只是两者都与TheParent“兼容”。

    TheChild ($call) 从其父级(类)继承属性_parent_property。但是,该属性未在该实例(对象)中初始化/设置,因此它仍然是 NULL

    【讨论】:

    • 是的,马克的回答有助于澄清这一点。无论如何,我赞成你花时间阅读和回复。谢谢=)
    猜你喜欢
    • 2023-02-04
    • 2017-12-16
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多