Php: redefinition of abstract method goes wrong

I think there is a problem in the implementation of PHP-OOP.

EDIT: Consider a more visual 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 reports that the following methods are illegal:

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

but when Animal :: Communicate is not abstract, but has a zero implementation, Php considers these methods to be legal. So, in my opinion, this is not so, because we do redefinition in both cases, and both cases are equal, so it seems that this is a mistake ...

The old part of the message:

Pay attention to 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) { ... }
    }
}

MyDecorator.php,

: MyDecorator:: Decorate() A\Decorator:: Decorate() MyDecorator.php on line...

Framework.php:: Decorator :

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

.

+3
3
+3

( ;), :

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

, , . :

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

. \A\Component?

: , 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(\A\Component $component) {}
    }

}

:

<?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) {}
    }

}
?>

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

, , , .

, : :

<?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) {}
    }


?>

- . .

+4

This has nothing to do with being abstract. This is due to the type of hint. The two method definitions are incompatible because you explicitly set the type argument \A\Component, and then try to overload the method with the help \B\Componentthat you cannot do, because it changes the signature of the method. Any subsequent declaration Decoratemust use the same type of prompt as its parent declaration, so that the method signatures are compatible.

+1
source

Source: https://habr.com/ru/post/1785702/


All Articles