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

Asked

Viewed 111 times

6

It is incorrect (or "semantically incorrect") to change the arguments in an extended class 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:

Foo('Error Processing Request');

This would be incorrect?

  • 1

    No... nothing wrong with that.

  • 1

    Why is the downvote? It is not a valid question, could explain the reason, do not worry I am not vengeful, I will not return downvotes, I just want to know where this the problem of the question to try to improve it

1 answer

6


In builder 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 don’t have to have polymorphism in this case.

You just need to make sure you’re not hurting the substitution principle Liskov. A derivative type cannot modify the constraints that did not exist in the original type, the substitution needs to 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 polymorphism. The problem will occur in polymorphic methods.

Polymorphic methods

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

Think you create a function that should receive one Bar. Obviously you can send a Foo for her since all Foo is a Bar. In that role you call m passing 3 arguments. But the m that will be called is that of Foo which 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);

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference. Note that this code has warnings depending on the version.

So this case is semantically wrong.

You might think that if it’s the opposite it might 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);

Behold not working on ideone. And in the repl it.. Also put on the Github for future reference.

Is that what you wanted? I don’t think so. It’s semantically wrong.

Can there be any situation that is correct? I think it can, but it probably wasn’t even supposed to have polymorphism there. Polymorphism presupposes that there is a perfect substitution.

  • 1

    He waited until 10:00 to win the hehehe hat :)

  • was before, you can see.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.