简体   繁体   中英

Parent class property set by parent method blank when accessing from child method

I'm having trouble understanding why I can access a property from my parent class, but it's NULL, even though it has already been set by the parent (and has not been knowingly reset). I thought it might be because that property was set by a private method, but no difference when I changed to public. Here's a radically simplified example:

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');

I worked around this by passing the parent property to the child when the child is constructed by the parent ie new TheChild($this->_parent_property) , but I still don't understand why $this->_parent_property is set to NULL when accessed from the child in my original example.

I do know that if I set this property from the parent constructor, I'd be able to access it just fine. I'm trying to understand why a property set by a parent method, and accessible by other parent methods, is not accessible from the child class which extends the parent.

Can anyone explain? Thanks!

The problem is that you're creating a new instance where the variable isn't set. The property is bound to a particular instance, so you're creating one instance of the parent and then from the parent another instance of the child,i which includes all the stuff creating a new parent would contain, including $_parent_property . When you read the value in the child, you're reading the value of a newly created parent, not the one you previously created.

In effect, you do this:

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

Calls: B = new TheChild() underneath the covers, this does new TheParent()

Print B->_parent_property (which was uninitialized)

Consider this similar example that will produce your expected result:

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();

In this example, the private method in TheParent is invoked on the same instance created by TheChild , setting the underlying instance variable.

You have a slightly wrong idea of how inheritance works.

TheParent is a class, and TheChild is a class based on the TheParent . $test now is an instance of TheParent . It has no idea that there is another class TheChild based on the class TheParent .

You create a new instance $call which is of type TheChild . This is, to use another word, a new object. It has nothing to do with $test , except that both are "compatible" to TheParent .

TheChild ( $call ) inherits the property _parent_property from its parent (class). However, that property is not initialised/set in that instance (object), so it is still NULL .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM