Home > database >  Why dont parent classes are not automatically destruct in php?
Why dont parent classes are not automatically destruct in php?

Time:07-28

I am trying to dig some PHP OOP features. Here is my sample codes

<?php

abstract class Animal{
    public $name;

    public function __construct($name)
    {
        $this->name = $name;
        echo 'animal instruct'  . "\n";
    }
    public function eat(){
        return $this->name . ' is eating food.'  . "\n";
    }

    public function __destruct()
    {
        echo "animal destruct"  . "\n";
    }
}

class Dog extends Animal{
    public $name;
    public function __construct($name)
    {
        parent::__construct($name);
    }

    public function bark(){
        return $this->name . ' is barking.'  . "\n";
    }

    public function __destruct()
    {
        echo "dog destruct"  . "\n";
        parent::__destruct();
        
    }
}

class Cat extends Animal{
    public $name;
    public function __construct($name)
    {
        parent::__construct($name);
    }

    public function meow(){
        return $this->name . ' is meowing.'  . "\n";
    }

    public function __destruct()
    {
        parent::__destruct();
        echo "cat destruct" . "\n";
    }
}

$bobby = new Dog('Bobby');
echo $bobby->bark();
echo $bobby->eat();

$cat = new Cat("cat");
echo $cat->meow();
echo $cat->eat();
?>

When I run the code , the output is as follow

animal instruct
Bobby is barking.
Bobby is eating food.
animal instruct
cat is meowing.
cat is eating food.
animal destruct
cat destruct
dog destruct
animal destruct

When I remove this code from child classes

parent::__destruct();

the parent class is not automatically destruct itself.

What I want to know is Do we need to destruct parent class in every child classes for some free memory space or PHP will do it itself?

CodePudding user response:

There are a few things to unpick here:

  • Once an object in PHP has no more references to it, the memory it uses will be freed. If it has the last reference to some other object, that object will also be freed, and so on. This is automatic, and largely invisible; you don't need to write any code in your class to make it happen, nor can you stop it happening, other than by keeping a reference to the object somewhere. (If there are circular references, they may not be freed immediately, but PHP will periodically check and free those as well.)
  • When the object is freed, PHP will run a method called __destruct, if it exists. This method isn't responsible for freeing the object, it's just happening as an effect of PHP deciding to do so. It gives you a chance to do extra cleanup or checks as well as what PHP does automatically.
  • When you inherit from a class, that inheritance is part of the definition of the object; creating an instance of the sub-class doesn't actually create two objects. So in your example, $bobby is an instance of Dog, and the memory that needs to be freed is the memory taken by that instance; there is no extra instance of Animal "inside" it.
  • When you define any method in both a parent class and a sub-class, the definition in the sub-class hides the one in the parent class. If you add a definition of eat() in class Dog, it will be called instead of the definition in Animal. The same is true with "magic" methods like __destruct: when $bobby is freed, the engine will call $bobby->__destruct(), and find the definition in class Dog instead of the one in class Animal. By calling parent::__destruct() inside the definition of Dog, you are explicitly asking to run the "hidden" definition.

So the answer to your final question:

Do we need to destruct parent class in every child classes for some free memory space or PHP will do it itself?

Is No. PHP will free the memory space of the object regardless of how you define the object; and there is no separate "parent memory" to free. It will additionally run the __destruct method on that object if one exists; that method will be resolved using the normal rules: look on sub-class first, else parent, and so on.

CodePudding user response:

From the manual:

The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.

So it says, the parent destructor won't be called automatically, as same is for the parent constructor.

If your parent class needs to do deconstruct work, you have to call it expliticly.

Short answer

The destructor will only be called on instances.

  • Related