Knowledge brings fear ... Prosthetic Conscious

Tuesday Apr 07, 2009

Consider the following coding problem

class A { ... }
class B extends A { ... }
List<A> aList = ...
List<B> bList = ...
List<A> getAList() {
    return bList;

}

This doesn't compile. Why? Because while A is a subclass of B, List<A> is not a sublclass of List<B>. Despite that, it's quite common that you'd want to do something like this.  Consider a more concrete example.

interface TreeNode { ... }
interface ContainerTreeNode extends TreeNode {
    List<TreeNode> getChildren();
}

class Tree(TreeNode rootNode) { ... }

To make themselves tree-storable, other classes just implement TreeNode or ContainerTreeNode. The problem is in the implementation of ContainerTreeNode. For example,

class Employee implements TreeNode { ... }
class Manager implements ContainerTreeNode {
    List<Employee> employees ...;
    ... 
    List<TreeNode> getChildren() {
        return employees;
   }
}

You'd like to be able to do this, but it won't compile for the reasons stated above. The solution is to use the <? extends T> idiom. Declare getChildren() as such,

 List<? extends TreeNode> getChildren();
Comments:

Post a Comment:
  • HTML Syntax: NOT allowed