[[Property:title|I2E: Combining Genericity and Inheritance]]
[[Property:weight|-3]]
[[Property:uuid|912e4c38-9add-e478-59c3-5c10aa75d784]]
Genericity and inheritance, the two fundamental mechanisms for generalizing classes, may be combined in two fruitful ways. 

The first technique yields '''polymorphic data structures'''. Assume that in the generic class <code>LIST [G]</code> the insertion procedure <code>put</code> has a formal argument of type <code>G</code>, representing the element to be inserted. Then with a declaration such as 
<code>
    pl: LIST [POLYGON]</code>

the type rules imply that in a call <code>pl.put (p)</code> the permitted types for the argument <code>p</code> include not just <code>POLYGON</code>, but also <code>RECTANGLE</code> (an heir of <code>POLYGON</code>) or any other type conforming to <code>POLYGON</code> through inheritance. 

The basic conformance requirement used here is the inheritance-based type compatibility rule: <code>V</code> conforms to <code>T</code> if <code>V</code> is a descendant of <code>T</code>. 

Structures such as <code>pl</code> may contain objects of different types, hence the name "polymorphic data structure". Such polymorphism is, again, made safe by the type rules: by choosing an actual generic parameter ( <code>POLYGON</code> in the example) based higher or lower in the inheritance graph, you extend or restrict the permissible types of objects in <code>pl</code>. A fully general list would be declared as 
<code>
                LIST [ANY]</code>

where <code>ANY</code>, a Kernel Library class, is automatically an ancestor of any class that you may write. 

The other mechanism for combining genericity and inheritance is '''constrained genericity'''. By indicating a class name after a formal generic parameter, as in 
<code>
                VECTOR [T -> NUMERIC]</code>

you express that only descendants of that class (here <code>NUMERIC</code>) may be used as the corresponding actual generic parameters. This makes it possible to use the corresponding operations. Here, for example, class <code>VECTOR</code> may define a routine <code>infix</code> "+" for adding vectors, based on the corresponding routine from <code>NUMERIC</code> for adding vector elements. Then by making <code>VECTOR</code> itself inherit from <code>NUMERIC</code>, you ensure that it satisfies its own generic constraint and enable the definition of types such as <code>VECTOR [VECTOR [T]]</code> . 

As you have perhaps guessed, unconstrained genericity, as in <code>LIST [G]</code> , may be viewed as an abbreviation for genericity constrained by <code>ANY</code>, as in 
<code>
                LIST [G -> ANY]</code>

Something else you may have guessed: if <code>ANY</code>, introduced in this session, is the top of the inheritance structure -- providing all classes with universal features such as <code>equal</code> to compare arbitrary objects and <code>twin</code> to duplicate objects -- then <code>NONE</code>, seen earlier in the notation <code>feature {NONE}</code>, is its bottom. <code>NONE</code> indeed conceptually inherits from all other classes. <code>NONE</code> is, among other things, the perceived type of the <code>Void</code> keyword which represents a void reference. 




