2010-03-04 14 views
7

Sto guardando alcune classi Java che hanno la seguente forma:Che cosa fa questo paradigma di generics Java e come si chiama?

 

public 
abstract 
class A <E extends A<E>> implements Comparable <E> { 

    public final int compareTo(E other) { 
     // etc 
    } 
} 

public 
class B extends A <B> { 
    // etc 
} 

public 
class C extends A <C> { 
    // etc 
} 

 

mio uso di "comparabile" qui è solo per illustrare un possibile utilizzo del parametro generico "E". Questo uso di generici/eredità ha un nome? A cosa serve?

La mia impressione è che questo consenta alla classe astratta di fornire un'implementazione comune di un metodo (come compareTo) senza doverlo fornire nelle sottoclassi. Tuttavia, in questo esempio, diversamente da un metodo ereditato, limiterebbe le sottoclassi a invocare il confronto su altre istanze della stessa sottoclasse, piuttosto che su una sottoclasse "A". Suona bene?

In ogni caso, è curioso di sapere se qualche guru là fuori l'ha già visto e sa cosa fa.

Grazie!

risposta

4

In C++, è noto come Curiously Recurring Template Pattern (CRTP). Non so se ha un nome diverso in Java (o anche se ha un nome), ma probabilmente ha scopi simili.

+0

Questa pagina wiki ha essenzialmente la spiegazione che stavo cercando, grazie! Ho trovato piuttosto interessante la nota sul polimorfismo "statico" in fase di compilazione. – Tom

+1

Qui c'è una bella discussione su Java: http://madbean.com/2004/mb2004-3/ Cerca l'intestazione "Altri trucchi con i parametri del tipo" –

+0

URL [dovrebbe essere incluso in una risposta per ulteriori letture ] (http://meta.stackexchange.com/q/8259). Questa risposta sembra fare molto affidamento sul contenuto di un URL e trarrebbe vantaggio da un riepilogo dell'URL incluso nella risposta. –

0

Credo che di solito si chiami semplicemente un tipo generico ricorsivo. Come sottolinea Tom Hawtin, probabilmente si desidera che la classe A < E si estenda A <E> >. L'uso più importante di questo modello è java.lang.Enum (che probabilmente sapevi considerando che hai scelto Comparabile <E> come interfaccia).

+0

No, non lo faresti. Dovresti semplicemente usare 'classe A '. – newacct

0

Non ha un nome e in genere non è utile. Probabilmente la persona che l'ha scritto non si rese conto che avrebbero potuto scrivere in questo modo invece:

class A<E> implements Comparable<E> 

mia impressione è che questo permette la classe astratta per fornire un attuazione comune di un metodo (come compareTo) senza avere per fornirlo nelle sottoclassi.

Non più di quanto class A<E>

Tuttavia, in questo esempio, a differenza di un metodo ereditato sarebbe limitare sottoclassi per invocare compareTo su altre istanze dello stesso sottoclasse, piuttosto che qualsiasi "A" sottoclasse. Suona bene?

No, non è corretto. Lo limita a invocare compareTo su E, qualunque sia lo E.