\begin{slide}{Vererbung und generische Polym. (I)}

\begin{itemize}\itemsep0pt\parskip 2pt
\item Vererbung: jedes Objekt bringt seine
  eigene Implementierung mit
\item Generizität: (gemeinsame) Implementierung
  wird durch (Typ/Funktions)-Parameter festgelegt
\end{itemize}
\begin{small}
\begin{verbatim}
interface I { void P (); }
static void Q (IList<I> xs) 
    { foreach (I x in xs) { x.P(); } }
static void R<C> (Action<C> S, IList<C> xs)
    { foreach (C x in xs) { S(x); } }
\end{verbatim}
\end{small}
für gleichzeitige Behandlung mehrerer Objekte\\
ist Vererbungspolymorphie meist ungeeignet

(z. B. \verb|Object.equals(Object o)| falsch, 
\verb|Comparable<T>.compareTo(T o)| richtig)

\end{slide}

\begin{slide}{Vererbung und generische Polym. (II)}

mit Sprachkonzepte \emph{Vererbung} 
ist Erweiterung des Sprachkonzeptes 
\emph{Generizität} wünschenswert:

beim Definition der Passung von parametrischen Typen
sollte die Vererbungsrelation $\le$ auf Typen
berücksichtigt werden.

\begin{itemize}
\item kovarianter Typparameter
  \verb|S extends T|
\item kontravarianter Typparameter
  \verb|S super T|
\end{itemize}

Anwendung z. B. bei generischen Sortierverfahren
für Collections.

\end{slide}
