Sortierte Listen mit Polymorphismus

Wave

Mitglied
Hallo,

ich probiere mit sortierten Listen (mit Kompositum) herum. Ich möchte aus der sortierten Liste Einträge löschen oder einfügen können, die Unterklassen der Klasse Moebel sind.
Die Methode einfuegen hat als Typ vom Parameter "Datenelement".
Wie kann ich von einer anderen Klasse z. B. VERWALTUNG aus ein Objekt einfügen?

Wenn ich z.B. folgendes in der Klasse VERWALTUNG machen würde:
Java:
public void eintragHinzufuegen(double pr, int anr, double pr, int anr, boolean drehbar){
    Datenelement eintragNeu = new Stuhl(pr, anr, pr, drehbar);
    liste.einfuegen(eintragNeu);
}
Bei mir gibt es aber auch Objekt vom Typ BETT, die ich einfügen könnte. Wie kann ich der Methode eintragHinzufuegen(...) in der Klasse VERWALTUNG beibringen, dass verschiedene Unterklassen zulässig sind, die jeweils andere Konstruktoren haben?

Java:
public class Sortierteliste{

    private Listenelement erster;
    
    public Sortierteliste(){
        erster = new Abschluss();
    }
    
    public Listenelement ersterGeben(){
        return erster;
    }
    
    public Datenknoten datenknotenGeben(Datenelement suchinhalt){
        return erster.datenknotenGeben(suchinhalt);
    }
    
    public void einfuegen(Datenelement de){
        erster = erster.sortiertEinfuegen(de);
    }
    
    public Datenelement ersterEntfernen(){
        Datenelement alterdatenknoteninhalt = erster.inhaltGeben();
        erster = erster.naechsterGeben();
        return alterdatenknoteninhalt;
    }
    
    public Datenelement entnehmen(Datenelement suchinhalt){     // Voraussetzung: Das Datenelement existiert.
        Datenelement alterdatenknoteninhalt = datenknotenGeben(suchinhalt).inhaltGeben();
        entfernen(suchinhalt);
        return alterdatenknoteninhalt;
    }
    
    public Datenelement entnehmen2(Datenelement suchinhalt){     // mit Fehlerabfang
        Datenelement alterdatenknoteninhalt = null;
        if(datenknotenGeben(suchinhalt) == null){
            System.out.println("Fehler!");
        }
        else{
            alterdatenknoteninhalt = datenknotenGeben(suchinhalt).inhaltGeben();
            entfernen(suchinhalt);
        }
        return alterdatenknoteninhalt;
    }
    
    public void entfernen(Datenelement suchinhalt){
        erster = erster.sortiertEntfernen(suchinhalt);
    }
    
    public boolean istLeer(){
        return (anzahlelementeGeben() == 0);
    }
    
    public int anzahlelementeGeben(){
        return erster.anzahldatenknotenGeben();
    }
    
    public void alledatenAusgeben(){
        erster.listendatenAusgeben();
    }
}

public abstract class Listenelement{
    
    public abstract Listenelement naechsterGeben();
    public abstract Datenelement inhaltGeben();
    public abstract Datenknoten datenknotenGeben(Datenelement suchinhalt);
    public abstract Listenelement sortiertEntfernen(Datenelement suchinhalt);
    public abstract Listenelement sortiertEinfuegen(Datenelement de);
    public abstract Datenknoten hintenEinfuegen(Datenelement de);
    public abstract Datenelement inhaltletzterGeben(Datenelement aktuellerinhalt);
    public abstract int anzahldatenknotenGeben();
    public abstract void listendatenAusgeben();
    
}

public class Abschluss extends Listenelement{
  
    public Listenelement naechsterGeben(){
        return this;
    }
  
    public Datenelement inhaltGeben(){
        return null;
    }
    
    public Datenknoten datenknotenGeben(Datenelement suchinhalt){
        return null;
    }
    
    public Listenelement sortiertEntfernen(Datenelement suchinhalt){
        return this;
    }
    
    public Datenknoten sortiertEinfuegen(Datenelement de){
        return new Datenknoten(this, de);
    }
    
    public Datenknoten hintenEinfuegen(Datenelement de){
        return new Datenknoten(this, de); 
    }
    
    public Datenelement inhaltletzterGeben(Datenelement aktuellerinhalt){
        return aktuellerinhalt;
    }
    
    public int anzahldatenknotenGeben(){
        return 0;
    }
    
    public void listendatenAusgeben(){
    }
}


public class Datenknoten extends Listenelement{

    private Listenelement naechster;
    private Datenelement inhalt;
    
    public Datenknoten(Listenelement le, Datenelement de){
        naechster = le;
        inhalt = de;
    }
    
    public void naechsterSetzen(Listenelement le){
        naechster = le;
    }
    
    public Listenelement naechsterGeben(){
        return naechster;
    }
    
    public Datenelement inhaltGeben(){
        return inhalt;
    }    
    
    public Datenknoten datenknotenGeben(Datenelement suchinhalt){
        if(inhalt.istGleich(suchinhalt)){
            return this;
        }
        else{
            return naechster.datenknotenGeben(suchinhalt);
        }
    }
    
    public Listenelement sortiertEntfernen(Datenelement suchinhalt){
        if(inhalt.istGleich(suchinhalt)){
            return naechster;
        }
        else{
            if(inhalt.istKleiner(suchinhalt)){
                naechster = naechster.sortiertEntfernen(suchinhalt);
            }
            return this;
        }
    }
    
    public Datenknoten sortiertEinfuegen(Datenelement de){
        if(inhalt.istGleich(de)){
            naechster = naechster.sortiertEinfuegen(de);
            return this;
        }
        else{
            return new Datenknoten(this, de);
        }
    }
    
    public Datenknoten hintenEinfuegen(Datenelement de){
        naechster = naechster.hintenEinfuegen(de);
        return this;
    }
    
    public Datenelement inhaltletzterGeben(Datenelement aktuellerinhalt){
        return naechster.inhaltletzterGeben(aktuellerinhalt);
    }
    
    public int anzahldatenknotenGeben(){
        return 1 + naechster.anzahldatenknotenGeben();
    }
    
    public void listendatenAusgeben(){
        inhalt.datenAusgeben();
        naechster.listendatenAusgeben();
    }
}


public abstract class Datenelement{

    public abstract void datenAusgeben();
    public abstract boolean istGleich(Datenelement de);
    public abstract boolean istKleiner(Datenelement de);
    
}


public abstract class Moebel extends Datenelement{

    protected double preis;
    protected int artnr;
    
    public Moebel(double pr, int anr){
        preis = pr;
        artnr = artnr;
    }
    
    public int artnrGeben(){
        return artnr;
    }
    
    public double preisGeben(){
        return preis;
    }
}


public class Stuhl extends Moebel{

    private boolean istdrehbar;
    
    public Stuhl(double pr, int anr, boolean drehbar){
        super(pr, anr);
        istdrehbar = drehbar;
    }
    
    public boolean istKleiner(Datenelement de){
        return preis < ((Moebel) de).preis;
    }
    
    public boolean istGleich(Datenelement de){
        return preis == ((Moebel) de).preis;
    } 
    
    public void datenAusgeben(){
        System.out.println("Preis: " + preis + ", Artikelnummer: " + artnr + ", Drehbar: " + istdrehbar + ".");
    }
}


public class Bett extends Moebel{

    private double laenge;
    private double breite;
    
    public Bett(double pr, int anr, double neuelaenge, double neuebreite){
        super(pr, anr);
        laenge = neuelaenge;
        breite = neuebreite;
    }
    
    public boolean istKleiner(Datenelement de){
        return preis < ((Moebel) de).preis;
    }
    
    public boolean istGleich(Datenelement de){
        return preis == ((Moebel) de).preis;
    } 
    
    public void datenAusgeben(){
        System.out.println("Preis: " + preis + ", Artikelnummer: " + artnr + ", Laenge: " + laenge + ", Breite: " + breite + ".");
    }
}
 
Zuletzt bearbeitet:
Danke, ich habe nun geschrieben:
Java:
public void eintragEinfuegen(Datenelement de){
        bettliste.einfuegen(de);
        bettliste.alledatenAusgeben();
    }
Das funktioniert.

Aber hier gibts ein Problem beim Suchen. Java lässt nicht zu, ein Objekt der Klasse MOEBEL zu erstelllen (Fehlermeldung: abstrakte Klasse...).

Java:
public void eintragEntfernen(double suchdatum){     // Preis
        if(eintragSuchen(suchdatum) == null){
            System.out.println("Keine Entfernung moeglich.");
        }
        else{
            bettliste.entfernen(new Moebel(suchdatum, 0));
            bettliste.alledatenAusgeben();
        } 
    }

Wie kann ich trotzdem nach einem Suchdatum, dass jede Unterklasse hat (z.B. preis oder artnr) suchen? Ich kann ja allgemein das Objekt MOEBEL als Oberklasse nicht erzeugen...
 
Du musst über die Liste laufen, und das Element rausfinden, auf das das Suchkriterium zutrifft. GANZ grob (und ohne die genaue Verwendung nachvollzogen zu haben, also im halb-pseudocode)
Java:
void entfernen(int datum)
{
    Datenelement aktuell = erstes;
    while (aktuell != null)
    {
        if (aktuell.getInhalt().getDatum() == datum)
        {
            System.out.println("Entferne "+aktuell);
            entferne(aktuell); 
            return;
        }
        else
        {
            aktuell = aktuell.getNächstes();
        }
    }
    System.out.println("Das war nicht drin");
}

Es wäre gut, wenn du die Aufgabenstellung posten würdest, und sagen würdest, was davon vorgegeben war.
 
Aufgabenstellung gekürzt:
Sortierte heterogene Liste erstellen mit den Methoden sortiertEinfuegen, sortiertLoeschen und suchen.

Ich hab nun mit deiner Hilfe folgendes rumprobiert... es gab keine Fehlermeldung. Gibt es da einfachere Möglichkeiten? Ich muss auf den DATENKNOTEN immer zugreifen, über das DATENELEMENT hab ich keine Chance, so wie ich die Aufgabe aufgezogen habe.

Java:
public void eintragEntfernen2(double suchdatum){
        Datenelement aktuell = bettliste.ersterGeben().inhaltGeben();
        while(aktuell != null){
            if(aktuell.preisGeben() == suchdatum){
                System.out.println(aktuell + " wurde entfernt.");
                bettliste.entfernen(aktuell);
            }
            else{
                aktuell = bettliste.datenknotenGeben(aktuell).naechsterGeben().inhaltGeben();
            }
        }
        System.out.println("Das Element konnte nicht gefunden und somit nicht geloescht werden.");
    }

Ich habe in der Liste zwei Objekte (eines von der Klasse STUHL und eines von der Klasse BETT) mit je gleichem Preis gespeichert.
Die Methode gibt aber scheinbar als Endlos folgendes seltsames aus:
Stuhl@2a0850f8 wurde entfernt.
Stuhl@2a0850f8 wurde entfernt.
...
Worauf wird da referenziert? Kann man das umgehen?
Danke!
 
Zuletzt bearbeitet:
Ja, der Grund weswegen ich nach der Aufgabenstellung gefragt hatte, war, dass daran einige "unkonventionell" ist. Abgesehen von den deutschen Bezeichnern :autsch: würde man einiges davon "in der Realität™" eben anders machen, aber zum Lernen kann das so OK sein...

Damit bei
System.out.println(aktuell + " wurde entfernt.");
was sinnvolles erscheint, muss 'toString' überschrieben sein. Aber in diesem Fall würde man dann wohl eher
System.out.println("Entferne:");
element.datenAusgeben();
schreiben.

Der Grund, warum das so oft erscheint, liegt in einer Zeile, die in meinem Pseudocode stand, aber in deinem Code noch fehlt 😉
 

Zurück
Oben