3

I have these two interfaces:

interface Observer
{
    public function notify(Observable $observable, ...$args);
}

interface Observable
{
    public static function register(Observer $observer);
    public function notifyObservers();
}

And here is what I am trying to implement:

abstract class EventHandler implements Observer
{
    abstract public function notify(Event $event, ...$args);
}

abstract class Event implements Observable
{
    private static $handlers = [];
    public static function register(EventHandler $handler)
    {
        self::$handlers []= $handler;
    }

    public function notifyObservers()
    {
        //notify loop here...
    }
}

Event is an Observable and EventHandler is an Observer, right?

So why php considers these implementation incompatible with their respective interfaces?


A simple test of what I meant by "compatible":

class CreateEvent extends Event {}

$createEventObj = new CreateEvent();
if ($createEventObj instanceof Observable) {
    echo 'Compatible';
} else {
    echo 'Incompatible';
}
tereško
  • 58,060
  • 25
  • 98
  • 150
CarlosCarucce
  • 3,420
  • 1
  • 28
  • 51

1 Answers1

1

This is because of type hinting. If your typehint is (Observable $observable) you should use exactly the same typehint in all implementation of this method in all sub-classes. Read more here http://php.net/manual/de/language.oop5.typehinting.php.

Andrej
  • 7,474
  • 1
  • 19
  • 21
  • Hi thanks for your answer. This section of the dos is not very clear about this topic unfortunately... =/. I updated my question to make it a bit clearer – CarlosCarucce Sep 01 '16 at 00:11
  • 1
    Well, objects are compatible that's true. But what makes them compatible?! Yes, the same interface Observable. When you define a method with CreateEvent you switch from general form to a specific one. That approach breaks the one of main OOP rules: write code for interfaces or program to interfaces but not for specific classes/implementations. @CarlosCarucce – Andrej Sep 01 '16 at 00:34
  • As alternative I am typechecking the Observer in `Event::register`. Any thoughts? – CarlosCarucce Sep 01 '16 at 00:56