Java has a nice solution: An ArrayList&lt;Ellipse&gt; is an ArrayList&lt;? extends Shape&gt;. But it is also an ArrayList&lt;? super Circle&gt;.<p>The former is &quot;read-only&quot; (can read elements which are all guaranteed to be shapes). The latter is &quot;write-only&quot; (we can add circles to it, but not all elements in it are guaranteed to be circles).<p>I use quotes because it is not strictly true, but any writes or reads will be of the sort that they don&#x27;t cause type problems. For instance you can call clear() on a ArrayList&lt;? extends Shape&gt;