Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Php: Overriding abstract method goes wrong

Tags:

php

I think there is a problem in php's OOP implementation.

EDIT: Consider more illustrative example:

abstract class Animal {

    public $name;

    // public function Communicate(Animal $partner) {}     // Works
    public abstract function Communicate(Animal $partner); // Gives error
}

class Panda extends Animal {

    public function Communicate(Panda $partner) {
        echo "Hi {$partner->name} I'm a Panda";
    }

}

class Human extends Animal {

    public function Communicate(Human $partner) {
        echo "Hi {$partner->name} I'm a Human";
    }

}

$john = new Human(); $john->name = 'John';
$mary = new Human(); $mary->name = 'Mary';
$john->Communicate($mary); // should be ok

$zuzi = new Panda(); $zuzi->name = 'Zuzi';
$zuzi->Communicate($john); // should give error

The problem is that when Animal::Communicate is an abstract method, php tells that the following methods are illegal:

"public function Communicate(Panda $partner)" "public function Communicate(Human $partner)"

but when Animal::Communicate is non-abstract but has zero-implementation Php thinks that these methods are legal. So in my opinion it's not right because we are doing override in both cases, and these both cases are equal, so it seems like it's a bug...

Older part of the post:

Please consider the following code:

Framework.php

namespace A
{
    class Component { ... }

    abstract class Decorator {
        public abstract function Decorate(\A\Component $component);
    }
}

Implementation.php

namespace B
{
    class MyComponent extends \A\Component { ... }
}

MyDecorator.php

namespace A
{
    class MyDecorator extends Decorator {
        public function Decorate(\B\MyComponent $component) { ... }
    }
}

The following code gives error in MyDecorator.php telling

Fatal error: Declaration of MyDecorator::Decorate() must be compatible with that of A\Decorator::Decorate() in MyDecorator.php on line ...

But when I change the Framework.php::Decorator class to the following implementation:

    abstract class Decorator {
        public function Decorate(\A\Component $component) {}
    }

the problem disappears.

like image 441
Lu4 Avatar asked Mar 05 '26 05:03

Lu4


2 Answers

I'm not sure (haven't tested it ;), but you declare this abstract function:

public abstract function Decorate(\A\Component $component);

So you should implement this EXACTLY like that. But you did this:

public function Decorate(\B\MyComponent $component) { ... }

That's not the same. Could you try to change that to \A\Component?

To all comments: fact of the matter is that this piece of PHP "runs"

namespace A
{
    class Component { }

    abstract class Decorator {
        public abstract function Decorate(\A\Component $component);
    }
}
namespace B
{
    class MyComponent extends \A\Component { }
}
namespace A
{
    class MyDecorator extends Decorator {
        public function Decorate(\A\Component $component) {}
    }

}

And this doesn't:

<?php
namespace A
{
    class Component { }

    abstract class Decorator {
        public abstract function Decorate(\A\Component $component);
    }
}
namespace B
{
    class MyComponent extends \A\Component { }
}
namespace A
{
    class MyDecorator extends Decorator {
        public function Decorate(\B\MyComponent $component) {}
    }

}
?>

With this error: PHP Fatal error: Declaration of A\MyDecorator::Decorate() must be compatible with that of A\Decorator::Decorate() in line 18

Now you can discuss all you like about how that should or should not be, but that's the problem with the code.

so, to satisfy my own curiosity: this is illegal too:

<?php
    class Component { }

    abstract class Decorator {
        public abstract function Decorate(Component $component);
    }

    class MyComponent extends Component { }
    class MyDecorator extends Decorator {
        public function Decorate(MyComponent $component) {}
    }


?>

It's not the namespaces or anything. It just doesn't seem legal.

like image 154
Nanne Avatar answered Mar 07 '26 18:03

Nanne


See http://bugs.php.net/bug.php?id=36601, this issues has been reported as a bug but was rejected because of laziness :D

like image 39
Paul Avatar answered Mar 07 '26 18:03

Paul



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!