2016-10-09 2 views
1

Ich versuche, mehrere Objekte verschiedener Typen durchzulaufen, die alle die gleiche Elternklasse erweitern. Zum Beispiel:Java-Vererbung, Looping durch jede Unterklasse

ArrayList<Enchant> enchants = new ArrayList<>(); 

Innerhalb des Verzauberungen Array würde Objekte von Klassen sein, die eine Enchant Klasse erweitern.

Zum Beispiel:

public class JumpBoost extends Enchant{ 
    public static Item generateItem(){ 
     return something; 
    } 
} 

Jedes Objekt in der Arraylist Verzauberungen ein Verfahren hätte genannt generateItem().

Ich möchte durch sie Schleife:

for(Enchant enchant : enchants){ 
    enchant.generateItem() 
} 

ich schon versucht, dies zu tun, aber ohne Glück aufgrund der Verzauberungs Klasse der generateItem() Verfahren nicht mit.

Ich brauche im Wesentlichen nur eine Möglichkeit, mehrere Objekte verschiedener Typen zu gruppieren und zu durchlaufen.

Antwort

2

Sie können Polymorphismus verwenden, um dieses Problem zu lösen.
Definieren Sie zunächst die Basisklasse/abstrakte Klasse/Schnittstelle mit der Methode generateItem(), leiten Sie die angegebenen Klassen ab und überschreiben/implementieren Sie die generateItem() -Methode.
Hier ist die Umsetzung mit Schnittstelle:

interface Base{ 
    void generateItem(); 
} 
class Derived1 implements Base{ 
    @Override 
    public void generateItem() { 
     System.out.println("generateItem() from Derived1"); 
    } 
} 
class Derived2 implements Base{ 
    @Override 
    public void generateItem() { 
     System.out.println("generateItem() from Derived2"); 
    } 
} 
class Main { 
    public static void main(String[] args) { 
     List<Base> list = new ArrayList<>(); 
     list.add(new Derived1()); 
     list.add(new Derived2()); 
     list.forEach(Base::generateItem); 
    } 
} 

Die Ausgabe lautet:

generateItem() from Derived1 
generateItem() from Derived2 

Weitere, Sie Polymorphismus here lesen kann.

+2

Sollte nicht die zweite Ausgabe von Derived2 sein? – SpiroMarshes

+0

Natürlich, danke! –

4

Der idiomatische Ansatz besteht darin, eine abstrakte generateItem() auf Enchant zu definieren. Wenn Sie aus irgendeinem Grund Enchant nicht ändern können, könnten Sie eine abstrakte Unterklasse von Enchant erstellen und alle Ihre Unterklassen davon erben lassen.

Sie könnten auch versuchen, eine Schnittstelle mit generateItem() zu erstellen, die alle Unterklassen implementieren und den Interface-Typ in der ArrayList speichern.

Wenn Sie aus irgendeinem Grund immer noch nichts tun können, sollten Sie Ihr Design überdenken. Aber als letzte Möglichkeit können Sie mit Reflection dynamisch auf die generateItem jeder einzelnen Unterklasse zugreifen. Rufen Sie einfach .getClass() an und suchen Sie dann die Methode und rufen Sie sie auf.

1

Geben Sie Enchant eine abstrakte Methode, die Unterklassen implementieren müssen. Es abstrakt zu machen bedeutet Enchant benötigt keine Definition der Methode, aber Unterklassen tun.

public class Enchant { 
    public abstract Item generateItem(); 
} 

Das Verfahren soll keine static Methode, wie Sie es in Ihrem Code haben. Es sollte eine Instanzmethode sein, da Sie es bei Instanzen von Enchant aufrufen.

-1

Machen Sie Verzauberung als Interface oder abstrakte Klasse und erweitern Sie sie in den abgeleiteten Klassen.