2010-10-10 4 views
5

in C++ können wir schreiben:Generisches Vererbung 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(); 
} 

Templat-Erbe zu erhalten.

Kann das gleiche in Java mit Generics getan werden?

Danke.

Edit: weitere Informationen über meine Absichten

In meinem Szenario Hinzufügen Ich habe zwei Unterklassen, Sprite und AnimatedSprite (die eine Unterklasse von Sprite ist). Der nächste Schritt ist ein PhysicalSprite, der den Sprites Physik hinzufügt, aber ich möchte, dass er sowohl von Sprite als auch von AnimatedSprite erben kann.

+1

+1, ich wusste nicht, C++ Vorlagen könnten das tun! (Dies könnte für Effekte wie dynamische Mixin-Komposition in Scala verwendet werden :) – missingfaktor

+0

@missingfaktor: google für das CRTP-Muster –

+0

@Armen: Dies ist kein Beispiel für CRTP-Muster. CRTP hat eine allgemeine Struktur "Klasse A: B ", was beim OP-Code nicht der Fall ist. – missingfaktor

Antwort

5

Nr. C++ Vorlagen sind much stronger als Java-Generika. Generics in Java dienen nur dazu, eine korrekte Typisierung während der Kompilierzeit sicherzustellen und sind nicht im generierten Bytecode enthalten - dies wird type erasure genannt.

In meinem Szenario habe ich zwei Unterklassen, Sprite und AnimatedSprite (die eine Unterklasse von Sprite ist). Der nächste Schritt ist ein PhysicalSprite, der den Sprites Physik hinzufügt, aber ich möchte, dass er sowohl von Sprite als auch von AnimatedSprite erben kann.

Vererbung ist nicht die einzige Form der Wiederverwendung von Code. Dieser Anwendungsfall kann auch mit anderen Mustern behandelt werden, beispielsweise einfach decoration. Betrachten Sie so etwas wie die folgenden:

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

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

PhysicalSprite in diesem Fall Delegierten würden die Sprite Teile bis zu einem gewissen Sprite-Instanz im Konstruktor zur Verfügung gestellt. Es wäre dann frei, eine eigene Handhabung für den Physikteil hinzuzufügen.

+0

rechnerisch und konzeptionell :) –

+0

Nicht 100% sauber imo, aber ich denke, es wird funktionieren. Vielen Dank! – monoceres

0

Nein, nicht genau so. Aber wenn Sie uns sagen, was genau Sie tun wollen, bin ich mir ziemlich sicher, dass es eine elegante Möglichkeit geben wird, das zu tun. Ich sehe keine Notwendigkeit für Vorlagen/Generika in Ihrem Beispiel.
Insbesondere scheint es Base1 und Base2 könnte von gemeinsamen Schnittstellen mit der Methode test profitieren.

+0

Ich habe weitere Informationen hinzugefügt :) – monoceres

+0

@monoceres Nun, Designmuster sind nicht meine starke Seite, aber es scheint, dass es schon einige Vorschläge gibt (und vielleicht bald einige mehr erfahrene Leute als ich ankommen werde, um zu helfen). –

1

Ach, nein.

Im Gegensatz zu C++, von dem angenommen werden kann, dass es für jede Instanziierung einer Vorlage eine andere Klassendefinition gibt, haben alle Instanzen eines generischen Typs die gleiche Laufzeitklasse in Java und daher die gleichen Methodendefinitionen. Generics (in Java) sind Kompilierzeit und werden zur Laufzeit nicht verfolgt.

Daher ist die Java Language Specification explictly forbids eine Art Paramater als übergeordnete Klasse oder implementierte Schnittstelle zu spezifizieren:

Die optionale Klausel in einer normalen Klassendeklaration erstreckt gibt die direkten Ober der aktuellen Klasse.

Super-: erweitert Classtype

wo Classtype eine qualifizierte oder unqualifizierte Klassennamen (mit optionaler Typargumente)

Umgehungen

  1. Anwendung ist die Dekorationsmuster wenn Sie Methoden, die von der Superklasse aufgerufen werden, nicht überschreiben müssen.
  2. Generieren Sie eine dedizierte Unterklasse für jede Instanziierung der Vorlage. Sie können dies zur Laufzeit zum Beispiel mit Hilfe von Javassist tun oder Quellcodetransformationen zur Kompilierzeit verwenden.