2010-10-10 19 views
5

in C++ possiamo scrivere:eredità generico in Java

#include <iostream> 

class Base1 
{ 
public: void test() { std::cout << "Base 1" << std::endl; } 
}; 

class Base2 
{ 
    public: void test() { std::cout << "Base 2" << std::endl; } 
}; 

template<class T> 
class Derived: public T 
{ 

}; 

int main() 
{ 
    Derived<Base1> d1; 
    Derived<Base2> d2; 
    d1.test(); 
    d2.test(); 
} 

Per ottenere l'ereditarietà su modelli.

Lo stesso può essere fatto in java usando i generici?

Grazie.

Edit: L'aggiunta di ulteriori informazioni circa le mie intenzioni

Nel mio scenario ho due sottoclassi, Sprite e AnimatedSprite (che è una sottoclasse di Sprite). Il passo successivo è un PhysicalSprite che aggiunge fisica agli sprite, ma voglio che sia in grado di ereditare sia da Sprite che da AnimatedSprite.

+1

+1, non sapevo che i modelli C++ potevano farlo! (Questo potrebbe essere usato per ottenere effetti come composizione mixin dinamica in Scala :) – missingfaktor

+0

@missingfaktor: google per il pattern CRTP –

+0

@Armen: Questo non è un esempio di pattern CRTP. Il CRTP ha una struttura generale 'classe A: B ', che non è il caso del codice OP. – missingfaktor

risposta

5

No. I modelli di C++ sono much stronger rispetto ai generici di Java. Generics in Java serve solo a garantire una corretta digitazione durante la compilazione e non è presente nel codice byte generato - questo è chiamato type erasure.

Nel mio scenario ho due sottoclassi, Sprite e AnimatedSprite (che è una sottoclasse di Sprite). Il passo successivo è un PhysicalSprite che aggiunge fisica agli sprite, ma voglio che sia in grado di ereditare sia da Sprite che da AnimatedSprite.

L'ereditarietà non è l'unica forma di riutilizzo del codice. Questo caso d'uso può essere gestito anche con altri modelli, come ad esempio il semplice decoration. Prendere in considerazione qualcosa di simile al seguente:

interface Sprite { ... } 
class StaticSprite implements Sprite { ... } 
class AnimatedSprite implements Sprite { ... } 

class PhysicalSprite implements Sprite, Physics { 
    PhysicalSprite(Sprite inner) { ... } 
    ... 
} 

PhysicalSprite sarebbe in questo caso delegato le parti Sprite per qualche caso Sprite fornito nel costruttore. Sarebbe quindi libero di aggiungere la propria gestione per la parte Fisica.

+0

computazionalmente e concettualmente :) –

+0

Non 100% clean imo, ma immagino che funzionerà. Grazie! – monoceres

0

No, non esattamente nello stesso modo. Ma se ci dici cosa esattamente vuoi fare, sono abbastanza sicuro che ci sarà un modo elegante per farlo. Non vedo alcun bisogno di modelli/generici nel tuo esempio.
In particolare, sembra che Base1 e Base2 possano beneficiare delle interfacce comuni con il metodo test.

+0

Ho aggiunto ulteriori informazioni :) – monoceres

+0

@monoceres Beh, i pattern di progettazione non sono il mio lato forte, ma sembra che ci siano già alcuni suggerimenti (e forse presto arriveranno ad aiutare alcune persone più esperte di me). –

1

Ahimè, no.

A differenza del C++, che può essere pensato per emettere una definizione di classe diversa per ogni istanza di un modello, tutte le istanze di un tipo generico condividono la stessa classe di esecuzione in Java e pertanto hanno le stesse definizioni di metodo. Generics (in Java) sono in fase di compilazione e non sono tracciati in fase di runtime.

Pertanto, il linguaggio Java Specification esplicitamente forbids per specificare un tipo di paramater come superclasse o interfaccia implementata:

opzionale estende la clausola in una dichiarazione di classe normale specifica la superclasse diretta della classe corrente.

Super: estende ClassType

dove ClassType è un nome di classe qualificato o non qualificato (con argomenti di tipo opzionale)

Soluzioni alternative

  1. Utilizzare il modello di decoratore se non è necessario sovrascrivere i metodi richiamati dalla super classe.
  2. Generare una sottoclasse dedicata per ogni istanza del modello. Puoi farlo al runtime usando, per esempio, Javassist, o usando le trasformazioni del codice sorgente in fase di compilazione.