title: PHP 7 return type inheritance
body: <p>I've implemented the repository pattern in my project without too many issues. To avoid repeating myself, I have implemented an <code>abstract</code> repository class that all of my repositories extend. Each repository has its own <code>interface</code> that it must implement.</p>
  
  <p>I have code similar to the following, which works fine:</p>
  
  <pre><code>class Model {}
  
  class User extends Model {}
  
  abstract class AbstractRepository
  {
      protected $model;
  
      public function find($id)
      {
          $class = $this-&gt;model;
  
          return new $class();
      }
  }
  
  interface UserRepositoryInterface
  {
      public function find($id);
  }
  
  class UserRepository extends AbstractRepository implements UserRepositoryInterface
  {
      protected $model = User::class;
  }
  </code></pre>
  
  <p>I want to start using return type declarations in my code, having upgraded to PHP 7.1. So I added a <code>?Model</code> return type to the <code>find</code> method in my <code>AbstractRepository</code> and a <code>?User</code> return type to the <code>UserRepositoryInterface</code>.</p>
  
  <pre><code>class Model {}
  
  class User extends Model {}
  
  abstract class AbstractRepository
  {
      protected $model;
  
      public function find($id): ?Model
      {
          $class = $this-&gt;model;
  
          return new $class();
      }
  }
  
  interface UserRepositoryInterface
  {
      public function find($id): ?User;
  }
  
  class UserRepository extends AbstractRepository implements UserRepositoryInterface
  {
      protected $model = User::class;
  }
  </code></pre>
  
  <p>Now, PHP complains that the declarations are incompatible, which I kind of expected.</p>
  
  <blockquote>
    <p>Fatal error: Declaration of AbstractRepository::find($id) must be compatible with AbstractRepositoryInterface::find($id): ?Model in /Users/jonathon/Desktop/test.php on line 21</p>
  </blockquote>
  
  <p>In another language, such as Java I would have considered using Generics to implement the repository, which would allow me to use the generic type in the method signatures.</p>
  
  <p>Is it possible to get this working so that:</p>
  
  <ul>
  <li>I have an interface and implementation for each repository</li>
  <li>I have an abstract class that is extended by each of my repositories, which does the majority of the work.</li>
  <li>I can continue using PHP 7's return type declarations, specifying a different return type for each different repository (e.g. <code>?User</code> for <code>UserRepositoryInterface</code> and <code>?Product</code> for <code>ProductRepositoryInterface</code>)?</li>
  </ul>
  
  <p>The way I see it now, I have a few options:</p>
  
  <ul>
  <li>Don't bother using return types.</li>
  <li>Change all the return type declarations to be <code>?Model</code> which all of my models extend.</li>
  <li>Repeat myself, getting rid of the abstract class</li>
  </ul>