title: Returning List of sub elements when extending a interface
body: <p>I'm developing a library and i have a faced an issue when overriding the return type as a List of sub elements.</p>
  
  <p>Initially its looked like this,</p>
  
  <pre><code>    Class Student {
      }
  
      public interface A {
          public Student isCurrentStudent(String name);
          public List&lt;Student&gt; getStudentList();
      }
  
      public interface B extends A {
          public List&lt;Student&gt; getColleges();
          public Student getBestFriend();
      }
  </code></pre>
  
  <p>Then i wanted to introduce SeniorStudent class and APIs for access SeniourStudent, so i came up with follows,</p>
  
  <pre><code>Class SeniorStudent extends Student{
  }
  
  public interface C extends A {
      public SeniorStudent isCurrentStudent(String name);
      public List&lt;SeniorStudent&gt; getStudentList();
      public void addStudent(Attributes s);
  }
  
  public interface D extends B,C {
      public List&lt;SeniorStudent&gt; getColleges();
      public Student getBestFriend();
  }
  </code></pre>
  
  <p>Problem starts with interface C and D. Since java supports for covariant return types, first method of C doesn't give an error. But when the return type is "List", it make's the trouble. So I have changed above interfaces to use generics.</p>
  
  <pre><code>public interface A &lt;T extends Student&gt; {
      public Student isCurrentStudent(String name);
      public List&lt;T&gt; getStudentList();
  }
  
  public interface B&lt;T extends Student&gt; extends A&lt;T&gt; {
      public List&lt;T&gt; getColleges();
      public Student getBestFriend();
  }
  
  public interface C extends A&lt;SeniorStudent&gt; {
      public SeniorStudent isCurrentStudent(String name);
      public List&lt;SeniorStudent&gt; getStudentList();
      public void addStudent(Attributes s);
  }
  
  public interface D extends B&lt;SeniorStudent&gt;,C {
      public List&lt;SeniorStudent&gt; getColleges();
      public SeniorStudent getBestFriend();
  }
  </code></pre>
  
  <p>I believe this design can be improved, such that implementor of class B can be restricted to use Student class only.</p>
  
  <p>What ultimately I wanted to have is, to provide clean API which can be used like this,</p>
  
  <pre><code>B bObject = getBObject();
  List&lt;Student&gt; studentList = bObject.getColleges();
  
  D dObject = getDObject();
  List&lt;SeniourStudent&gt; seniorStudentList = dObject.getColleges();
  </code></pre>
  
  <p>The whole problem would be solved if there is a way to override the return type when it is a List of sub elements.</p>
  
  <p>Since my actual code is much larger, I have used simple example here to describe the problem. Hope its clear enough.</p>
  
  <hr>
  
  <p><strong>EDIT</strong></p>
  
  <p>Introducing a BS super type for B would solve the problem. But is it the cleaner way?</p>
  
  <p><img src="https://i.stack.imgur.com/jfdbS.png" alt="class diagram when introducing SB"></p>
  
  <pre><code>public interface A &lt;T extends Student&gt; {
      public Student isCurrentStudent(String name);
      public List&lt;T&gt; getStudentList();
  }
  
  public interface BS&lt;T extends Student&gt; extends A&lt;T&gt; {
      public List&lt;T&gt; getColleges();
      public Student getBestFriend();
  }
  
  public interface B extends BS&lt;Student&gt; {
      public List&lt;Student&gt; getColleges();
      public Student getBestFriend();
  }
  
  public interface C extends A&lt;SeniorStudent&gt; {
      public SeniorStudent isCurrentStudent(String name);
      public List&lt;SeniorStudent&gt; getStudentList();
      public void addStudent(Attributes s);
  }
  
  public interface D extends BS&lt;SeniorStudent&gt;,C {
      public List&lt;SeniorStudent&gt; getColleges();
      public SeniorStudent getBestFriend();
  }
  </code></pre>
  
  <p>Thanks,</p>