title: Php: Overriding abstract method goes wrong
body: <p>I think there is a problem in php's OOP implementation.</p>
  
  <p><strong>EDIT:</strong> Consider more illustrative example:</p>
  
  <pre><code>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-&gt;name} I'm a Panda";
      }
  
  }
  
  class Human extends Animal {
  
      public function Communicate(Human $partner) {
          echo "Hi {$partner-&gt;name} I'm a Human";
      }
  
  }
  
  $john = new Human(); $john-&gt;name = 'John';
  $mary = new Human(); $mary-&gt;name = 'Mary';
  $john-&gt;Communicate($mary); // should be ok
  
  $zuzi = new Panda(); $zuzi-&gt;name = 'Zuzi';
  $zuzi-&gt;Communicate($john); // should give error
  </code></pre>
  
  <p>The problem is that when Animal::Communicate is an abstract method, php tells that the following methods are illegal:</p>
  
  <p>"public function  Communicate(Panda $partner)"
  "public function  Communicate(Human $partner)"</p>
  
  <p>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...</p>
  
  <p><strong>Older part of the post:</strong></p>
  
  <p>Please consider the following code:</p>
  
  <p><strong>Framework.php</strong></p>
  
  <pre><code>namespace A
  {
      class Component { ... }
  
      abstract class Decorator {
          public abstract function Decorate(\A\Component $component);
      }
  }
  </code></pre>
  
  <p><strong>Implementation.php</strong></p>
  
  <pre><code>namespace B
  {
      class MyComponent extends \A\Component { ... }
  }
  </code></pre>
  
  <p><strong>MyDecorator.php</strong></p>
  
  <pre><code>namespace A
  {
      class MyDecorator extends Decorator {
          public function Decorate(\B\MyComponent $component) { ... }
      }
  }
  </code></pre>
  
  <p>The following code gives error in <strong>MyDecorator.php</strong> telling</p>
  
  <p>Fatal error: Declaration of MyDecorator::Decorate() must be compatible with that of A\Decorator::Decorate() in MyDecorator.php on line ...</p>
  
  <p>But when I change the Framework.php::Decorator class to the following implementation:</p>
  
  <pre><code>    abstract class Decorator {
          public function Decorate(\A\Component $component) {}
      }
  </code></pre>
  
  <p>the problem disappears.</p>