So in the context of "List<? extends Dog>", the compiler (conceptually) treats the method as "public boolean add(? extends Dog e)". Since it doesn't know what type "? extends Dog" is going to represent, it can't accept a Collie object at that point.
subject: How Does the Compiler Know Not To Allow Adding to a Generic List With a Wildcard?