Generische Klassen "FlaschenRegal"

Mikesh

Mitglied
Hey,

ich möchte gerne eine generische Klasse "Weinregal" implementieren.

Aber von vorne. Ich habe eine generische Klasse Flaschen
Java:
public class Flasche<T extends Fluessigkeit> {
    private String etikett;
    private T inhalt = null;

    public void fuellen(T inhalt) {
        this.inhalt = inhalt;
    }
   
    public void beschriften(String text) {
        etikett = text;
    }
   
    public T gibInhalt() {
        return inhalt;
    }
   
    public String gibEtikett() {
        return etikett;
    }
   
    public T ausleeren() {
        T resInhalt = inhalt;
        inhalt = null;
        return resInhalt;
    }
   
    public boolean istLeer() {
        return inhalt == null;
    }
   
    public String toString() {
        return "Flasche \"" + etikett + "\", " + inhalt;
    }
   
}

In meiner Main fülle ich diese Flaschen mit Inhalt
Code:
Wein Chianti = new Wein("Chianti", 0.7);
        Wein Babera = new Wein("Babera", 1.0);
       
       
        Flasche<Wein> flasche0 = new Flasche<>();
        Flasche<Wein> flasche1 = new Flasche<>();
        Flasche<Wein> flasche2 = new Flasche<>();
        Flasche<Wein> flasche3 = new Flasche<>();
       
        flasche0.fuellen(Chianti);
        flasche1.fuellen(Babera);
        flasche2.fuellen(Chianti);
        flasche3.fuellen(Babera);

Das klappt alles soweit! Ich möchte nun eine weitere generische Klasse FlaschenRegal implementieren . Diesem Regal möchte ich dann gerne meine flasche0 ,flasche1 usw hinzufügen. Das ganz habe ich mir so vorgestellt dass mein Regal durch eine ArrayList oder Array repräsentiert wird.
Java:
import java.util.ArrayList;

public class FlaschenRegal<T extends Fluessigkeit> {

    private T[] regal;
    private int kapazität;
   

    public FlaschenRegal(int kapazität) {
        this.kapazität = kapazität;
       
       

    }
   


   
    public void ablegen(T flasche, int pos){

        regal[pos] = flasche;
       
       
        }
       
    }

Leider funktioniert das so gar nicht. Ich kann auch kein generisches Array vom Typ T generieren. Hat mir jemand einen Denkanstoß, ich bin komplett auf dem Holzweg.

Beste Grüße und ein schönes Wochenende
Mikesh
 
Mit class FlaschenRegal<T extends Fluessigkeit> gibst du ja auch nicht an, dass das Regal Flaschen enthalten soll, sondern Flüssigkeiten. Du solltest wohl eher schreiben: class FlaschenRegal<T extends Flasche<?>>, um zu sagen: Das ist ein Regal lauter Flaschen mit beliebigen Flüssigkeiten.

Ansonsten stimme ich @Robat zu: Verwende einfach eine existierende Collection Klasse.
 
Okai hab das jetzt mal probiert aber ich steig komplett nicht durch gerade... Das mit extends Flasche dachte ich mir auch schon, aber in der Aufgabe steht es soll extends Flüssigkeiten sein. Habt ihr mir vielleicht einen Fetzen Code der wenigstens zeigt wie ich das mit dem Objekt Array oder List richtig hinbekomme? Reicht auch allgemein. Komm gerade nicht dahinter
 
Na gut, du kannst den Typparameter natürlich auch für eine Flüssigkeit verwenden, in welchem Fall dein Regal dann eben ein Array von Flasche<T> enthalten kann und du dieses Array dann ensprechend mit Flasche[kapazität] instanziieren könntest.
 
Oder noch mal die Variante mit einer Collection
Java:
List<T> regal = new ArrayList<>();
 
Es klappt jetzt zwar aber wirklich überzeugt bin ich von der Sachen noch nicht die ich da gerade fabriziere.
Java:
public class FlaschenRegal<T extends Fluessigkeit > {
   
    private int kapazität;
    private ArrayList <Flasche<T>> regal;
   
   
    public FlaschenRegal(int kapazität){
        this.kapazität = kapazität;
        regal = new ArrayList<>();
   
       
    }

    public void ablegen( Flasche<T> flasche){
        if(regal.size() <= kapazität){
            regal.add(flasche);
           
        }
       
    }
   
    public void ausgabe(){
        for(Flasche element: regal){
            System.out.println(element);
        }
    }

Werde jetzt nochmal die Sache mit den Collections probieren.Dachte eigentlich dass ich die Generischen Klassen einigermaßen verstanden haben, aber das mit diesem Array wirft mich gerade irgendwie aus der Bahn 😀
 
Java:
public abstract class AbstractWein
{
    public abstract String getName();
}

public class CabernetFranc extends AbstractWein
{
    @Override
    public String getName()
    {
        return this.getClass().getSimpleName();
    }
   
}
public class CabernetSauvignon extends AbstractWein
{
    @Override
    public String getName()
    {
        return this.getClass().getSimpleName();
    }
}
public class Chianti extends AbstractWein
{
    @Override
    public String getName()
    {
        return this.getClass().getSimpleName();
    }
}
public class Dornfelder extends AbstractWein
{
    @Override
    public String getName()
    {
        return this.getClass().getSimpleName();
    }
}
public class Merlot extends AbstractWein
{
    @Override
    public String getName()
    {
        return this.getClass().getSimpleName();
    }
}
/**
 * Den Spass am Einfuegen an einer bestimmten Stelle will ich dir nicht nehmen.
 * Schau dir dafuer "Datenstrukturen und Algorithmen" in "Java ist auch eine Insel" an
 */
public class WeinSchrank<T extends AbstractWein>
{
    private final List<T> wein_liste = new ArrayList<>();
    public void inDenWeinschrank(T t)
    {
        wein_liste.add(t);
    }
    public void ausDemWeinschrank(T t)
    {
        wein_liste.remove(t);
    }
    public void gibDenWeinschrankInhalt()
    {
        for (T t : wein_liste)
        {
            System.out.println(t.getName());
        }
    }
}
Java:
public class Weinkeller
{

    public static void main(String[] args)
    {
        List<AbstractWein> wein_liste = new ArrayList<>();
        wein_liste.add(new CabernetFranc());
        wein_liste.add(new CabernetSauvignon());
        wein_liste.add(new Chianti());
        wein_liste.add(new Dornfelder());
        wein_liste.add(new Merlot());

        WeinSchrank<AbstractWein> weinschrank = new WeinSchrank<>();
        int soll_inhalt_an_flaschen = 100;
        for (int i = 0; i < soll_inhalt_an_flaschen; i++)
        {
            int x = (int) (Math.random() * wein_liste.size());
            weinschrank.inDenWeinschrank(wein_liste.get(x));
        }

        weinschrank.gibDenWeinschrankInhalt();

    }

}
 
Java:
public abstract class AbstractWein
{
    public abstract [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string']String[/URL] getName();
}

public class CabernetFranc extends AbstractWein
{
    @Override
    public [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string']String[/URL] getName()
    {
        return this.getClass().getSimpleName();
    }
  
}
public class CabernetSauvignon extends AbstractWein
{
    @Override
    public [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string']String[/URL] getName()
    {
        return this.getClass().getSimpleName();
    }
}
public class Chianti extends AbstractWein
{
    @Override
    public [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string']String[/URL] getName()
    {
        return this.getClass().getSimpleName();
    }
}
public class Dornfelder extends AbstractWein
{
    @Override
    public [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string']String[/URL] getName()
    {
        return this.getClass().getSimpleName();
    }
}
public class Merlot extends AbstractWein
{
    @Override
    public [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string']String[/URL] getName()
    {
        return this.getClass().getSimpleName();
    }
}

Das ist etwas wo ich überhaupt nicht konform gehe.
Wozu x Klassen erstellen, welche sich nur im Klassennamen unterscheiden?

Da ist es doch deutlich besser nur die Klasse Wein zu erstellen welche die Eigenschaft "typ" hat. Diese Eigenschaft kann auch ein Enum sein. Der Typ wird entsprechend im Konstruktor mitgegeben.
 
@MoxxiManagarm
Diente nur der Veranschaulichung, weil es eben um <T extends Something> ging. Ein Enum ist gut und sehr praktisch, jedoch würde ich hier den Weg über XML gehen, schon der Wiederverwendbarkeit wegen.
 
Da ich nicht einfach Code kopieren wollte, hab ich selber nochmal an meinem Code gebastelt. Die Regalklasse sieht nun wie folgt aus.
Java:
import java.lang.reflect.Array;
import java.util.ArrayList;

public class FlaschenRegal<T extends Fluessigkeit> {

    private int kapazität;
    private Flasche<T>[] regal;

    @SuppressWarnings("unchecked")
    public FlaschenRegal(int kapazität) {
        this.kapazität = kapazität;
        regal = new Flasche[kapazität];

    }

    public void ablegen(Flasche<T> flasche, int pos)
            throws IllegalArgumentException {
        if (regal[pos] == null) {
            regal[pos] = flasche;
        } else {
            throw new IllegalArgumentException();
        }
    }

    public Flasche<T> entnehmen(int pos) throws IllegalArgumentException {
        if (regal[pos] == null) {
            throw new IllegalArgumentException();

        }
        Flasche<T> tmp = regal[pos];
        regal[pos] = null;
        return tmp;

    }

    public void ausgabe() {
        for (Flasche<T> flasche : regal) {
            if (flasche == null) {
                System.out.println("leer");
            } else {

                System.out.println(flasche.gibInhalt());
            }
        }

    }

    public double gesamtvolumen() {
        double liter = 0;
        for (Flasche<T> flasche : regal) {
            if (flasche != null) {
                liter += flasche.gibInhalt().gibLiter();

            }
        }return liter;

    }
    public boolean istFrei(int pos){
        if(regal[pos] == null){
            return true;
           
        }else{
            return false;
        }
    }
    public int kapazitaet(){
        return regal.length;
    }

}
 
Ja, passt. Zwei Sachen nur noch:
1. Anscheinend brauchst du private int kapazität; nicht. Die Kapazität des Arrays nimmst du ja direkt aus array.length
2. Du könntest:
Java:
public boolean istFrei(int pos){
  if (regal[pos] == null) {
    return true;
  } else {
    return false;
  }
}
refactoren zu: return regal[pos] == null;
Das geht immer, wenn du if-Anweisungen der Form: if (c) return true/false; else return false/true; hast.
 

Zurück
Oben