Is it incorrect to change the arguments in an extended classes in PHP?

6

Is it incorrect (or "semantically incorrect") to change the arguments in an extended classes in PHP?

For example I created this class:

class Bar
{
    public function __construct($message, $code, $timer)
    {
        var_dump($message, $code);
    }
}

class Foo extends Bar
{
    public function __construct($message)
    {

        parent::__construct($message, 0, time());
    }
}

So I call it like this:

Foo('Error Processing Request');

Would this be incorrect?

    
asked by anonymous 30.12.2016 / 23:00

1 answer

6

In constructor there is no problem some because there is effectively no polymorphism in it. You can only call the constructor of the specific class you want, you do not have to have polymorphism in this case.

Just check to see if you are not hurting Liskov replacement principle . A derived type can not modify constraints that did not exist in the original type, the substitution must be perfect. But there is an analysis that depends on strong context and involves all kinds.

The same goes for any method that does not want the polymorphism. The problem will occur in polymorphic methods.

Polymorphic methods

Let's say you have a method m in Bar with three parameters, and in Foo this method has only one parameter.

You think you create a function that should get a Bar . Obviously you can send Foo to it since all Foo is Bar . In this function you call m passing 3 arguments. But the m that will be called is the Foo that only has 1 parameter. 2 parameters will be discarded and will not produce what you expect.

function m(Bar $x) {
    $x->m('Error Processing Request', 10, 1000000000);
}
class Bar {
    public function m($message, $code, $timer) {
        echo "Bar\n";
        var_dump($message, $code, $timer);
    }
}
class Foo extends Bar {
    public function m($message) {
       echo "Foo\n";
       parent::m($message, 0, time());
    }
}
m(new Foo);

See working on ideone and on PHPSandBox . Note that this code has warnings depending on the version.

So this case is semantically wrong.

You may think that if it is the opposite it may work.

function m(Bar $x) {
    $x->m('Error Processing Request');
}
class Bar {
    public function m($message) {
        echo "Bar\n";
        var_dump($message);
    }
}
class Foo extends Bar {
    public function m($message, $code, $timer) {
        var_dump($code, $timer);
        echo "Foo\n";
        parent::m($message);
    }
}
m(new Foo);

See running on ideone .

Was it what you wanted? I think not. It's semantically wrong.

Can there be any situation that is correct? I think it may, but it probably was not even to have polymorphism there. The polymorphism assumes that there is a perfect substitution.

    
31.12.2016 / 00:59