3

I was playing around with a couple of classes to understand the relationship between parent and child. I setup the parent to have a constructor that calls an init method. Then when I add an init method to the child, it should override the parent init, shouldn't it? But what is happening is that both methods are being called.

To test this, I wrote a class named Model and a child called Instance. Here is the code:

$try = new Instance;
echo $try;

class Model{

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

    public function init()
    {        
        return $this->className();   
    }

    public function __toString()
    {
        return $this->className();
    }

    public static function className()
    {
        return get_called_class();
    }

}

class Instance extends Model
{
    public function init()
    {
        echo "tada! ";
     }
}

Gives the following output:

tada! Instance.

In class Model, I use the magic method __toString() to return the class name as a string. The constructor of the parent calls the parent init() method, which in this case echoes the class name.

My understanding is that if I write a child class, in this case the class is called Instance, with an init() method, it would overwrite the parent init() method, but that is not what is happening. In this case, it returns both init mehtods and I have no idea why. Can anyone explain this?

0

4 Answers 4

3

The fact is -

When you instantiate an object of Class "Instance" using "$try = new Instance;". it calls the constructor and since child class overrides "init" method, it prints "tada!".

On the other line you echo the object of Class "Instance" using "echo $try;" and a magic method __toString() implemented in parent class. So it print "Instance" as class name.

You can run only $try = new Instance; that will print only "tada!".

Sign up to request clarification or add additional context in comments.

2 Comments

contractor? You mean constructor :)
thank you also for your answer, it helped me understand how it works.
2

You are running two different commands. First you are instantiating the class with $try = new Instance; which is calling __construct. The __construct() in the parent class is calling init() which is using the child init() and returning tada!. Create a blank constructor in the child class to override the parent constructor.

The second command is when you echo the class: echo $try; using __toString() which is echoing Instance as defined in the parent class.

You can also add to a parent constructor by using:

public function __construct() {
  ...code...
  parent::__construct();
  ...code...
}

1 Comment

thank you for your answer and suggestions, it helped me understand how it works.
0

Reason :

Since you don't have any constructor defined for your child class, the parent class constructor will be fired and that is why you get that output.

Explanation :

When you do

$try = new Instance;

The parent class constructor gets fired and it will call the init() which in turn calls the className() that does the get_called_class() , so eventually your init() in the child class will be called and you get the output "tada!" first.

And when you do..

echo $try;

The __toString() is called and returns you the class name Instance

So basically , If you had a constructor on your child class , you will not be getting the output "tada!"

Comments

0

In this case, it returns both init mehtods

No it doesn't;

'tada!' is being echoed by Instance::init() and 'Instance' is being echoed by Model::__toString().

1 Comment

So, just for 100% clarity, when defining the magic _toString() method, anything defined in that method will be printed if the object itself is echoed, as I did with echo $try; Thank you everyone for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.