Schnittstellen

JavaIsTheBest

Bekanntes Mitglied
Hallo,
ich wollte mal fragen, ob meine Implementierung soweit stimmt, da ich zu dieser Aufgabe keine Lösung habe.

Java:
public interface Container {
    public int size();
    public boolean isEmpty();
    public boolean isFull();
}
Java:
public interface StackQueueContainer extends Container{
public String putLast(String s);
}
Java:
public interface Stack extends StackQueueContainer{
    public String getLast();
}
Java:
public interface Queue extends StackQueueContainer {
    public String getFirst();
}
Java:
public interface Deque extends Stack, Queue {
    public boolean putFirst(String s);
}
 

Anhänge

  • schnittstellen.PNG
    schnittstellen.PNG
    68,2 KB · Aufrufe: 38

JavaIsTheBest

Bekanntes Mitglied
Und was haltet ihr von meiner Implementierung?

Java:
public class StackQueueContainerImpl implements Container {
    protected int size;
    protected String[] container;
    protected int cardinality;
  
    public StackQueueContainerImpl(int n){
        container=new String[n];
    }
    public int size(){
        return size;
    }
    public int cardinality(){
        return cardinality;
    }
    public boolean isEmpty(){
        return size==0;
    }
    public boolean isFull(){
        return cardinality<size;
    }
    public boolean putLast(String s){
        if(isFull()) return false;
        container[cardinality]=s;
        cardinality++;
        return true;
    }

}
Java:
public class StackImpl extends StackQueueContainerImpl {
  
    public StackImpl(int n){
        super(n);
    }
    public String getLast(){
        if(isEmpty()) return null;
        String s= container[cardinality-1];
        container[cardinality-1]=null;
        cardinality--;
        return s;
    }
  
}
Java:
public class QueueImpl extends StackQueueContainerImpl{
  
    public QueueImpl(int n){
        super(n);
    }
    public String getFirst(){
        if(isEmpty()) return null;
        String s=container[0];
        container[0]=null;
        cardinality--;
        return s;  
    }
}
Java:
public class DequeImpl extends QueueImpl {
  
    public DequeImpl(int n){
        super(n);
    }
    public boolean putFirst(String s){
        if(isFull()) return false;
        container[cardinality-1]=s;
        return true;
    }
    public String getLast(){
        if(isEmpty()) return null;
        String s= container[cardinality-1];
        container[cardinality-1]=null;
        cardinality--;
        return s;
    }
}

Soll ich zur besseren Übersicht ein UML zeichnen?
 

Anhänge

  • Unbenannt.PNG
    Unbenannt.PNG
    24,9 KB · Aufrufe: 15

mrBrown

Super-Moderator
Mitarbeiter
UML ist bei sowas immer sinnvoll ;)

Ich würde StackQueueContainerImpl abstrakt machen, eine Instanz davon ist ja sowieso nicht wirklich nutzbar.

Die Implemenation solltest du auch vllt noch mal überarbeiten ;)
Was sollen zB size und cardinality, size wird niemals ein Wert zugewiesen...
 

JavaIsTheBest

Bekanntes Mitglied
Das ist zwar kein Klassendiagramm, aber es erfüllt seinen Zweck. :)
size hab ich jetzt einen Wert zugewiesen und cardinality gibt die tatsächliche Anzahl, der Elemente an.

Was mir aufgefallen ist:

1. Die Kardinalität ist in der Aufgabe gar nicht erwähnt. Das ist aber trotzdem richtig so, dass ich es definiert habe?
2. In den Klassen DequeImpl und StackImpl hab ich die Methode getLast() implementiert. Hätte ich die doppelte Methodenimplementierung auch verhindern können? Oder, ist das so in Ordnung?
3. War es gut, dass ich die Attribute protected gemacht habe oder wäre private besser gewesen? Wäre das Array private, dann hätte ich in den Unterklassen nicht mehr drauf zugreifen können. Also ist protected hier richtig?
4. Was sagt ihr zu meinem Code?

Java:
public abstract class StackQueueContainerImpl implements Container {
    protected int size;
    protected String[] container;
    protected int cardinality;
   
    public StackQueueContainerImpl(int n){
        container=new String[n];
        size=n;
        cardinality++;
    }
    public int size(){
        return size;
    }
    public int cardinality(){
        return cardinality;
    }
    public boolean isEmpty(){
        return size==0;
    }
    public boolean isFull(){
        return cardinality<size;
    }
    public boolean putLast(String s){
        if(isFull()) return false;
        container[cardinality]=s;
        cardinality++;
        return true;
    }

}
Java:
public class QueueImpl extends StackQueueContainerImpl implements Queue{
   
    public QueueImpl(int n){
        super(n);
    }
    public String getFirst(){
        if(isEmpty()) return null;
        String s=container[0];
        container[0]=null;
        cardinality--;
        return s;   
    }
}
Java:
public class StackImpl extends StackQueueContainerImpl implements StackQueueContainer {
   
    public StackImpl(int n){
        super(n);
    }
    public String getLast(){
        if(isEmpty()) return null;
        String s= container[cardinality-1];
        container[cardinality-1]=null;
        cardinality--;
        return s;
    }
   
}
Java:
public class DequeImpl extends QueueImpl implements Deque {
   
    public DequeImpl(int n){
        super(n);
    }
    public boolean putFirst(String s){
        if(isFull()) return false;
        container[cardinality-1]=s;
        return true;
    }
    public String getLast(){
        if(isEmpty()) return null;
        String s= container[cardinality-1];
        container[cardinality-1]=null;
        cardinality--;
        return s;
    }
}
 

Anhänge

  • Schnittstellen.png
    Schnittstellen.png
    16,3 KB · Aufrufe: 18
  • Klassenimplementierung.png
    Klassenimplementierung.png
    22,7 KB · Aufrufe: 27

Meniskusschaden

Top Contributor
Du solltest dir den Gebrauch von size noch einmal ansehen. Teilweise nutzt du es so, als ob es die Gesamtgröße repräsentiert, teilweise so, dass es die aktuelle Anzahl der Elemente repräsentiert. Das wird also noch nicht funktionieren.
 

Meniskusschaden

Top Contributor
Im Konstruktor von StackQueueContainerImpl setzt du das Attribut size auf n und soweit ich sehe, ändert size sich dann nicht mehr. Es enthält also die Gesamtgrösse, wodurch die Methode size() fehlerhaft ist, die ja laut Aufgabenstellung die Anzahl der aktuell gespeicherten Elemente liefern soll.

Deine Methode isEmpty liefert true, falls size==0 ist, was aufgrund der vorigen Erklärung niemals passieren kann. In ein paar anderen Methoden hast du es ähnlich gemacht.
 

Meniskusschaden

Top Contributor
1. Die Kardinalität ist in der Aufgabe gar nicht erwähnt. Das ist aber trotzdem richtig so, dass ich es definiert habe?
Das ist schon eine vernünftige Idee. Ich würde es aber lieber nicht Kardinalität nennen, denn damit assoziiert man ja eher die aktuelle Anzahl der Elemente und für die ist bereits size vorgesehen (zumindest für die Methode size(), so dass es sinnvoll ist, das Attribut size auch entsprechend zu verwenden).

EDIT: Da du ein Array verwendest, kannst du die Gesamtanzahl aber auch dort abfragen, so dass du auch mit einer Variablen auskommen kannst.
 

JavaIsTheBest

Bekanntes Mitglied
Für die Anzahl der aktuellen Elemente, habe ich jetzt size genommen. Und die Variable capacity habe ich durch container.length ersetzt, so dass ich eine Variable weniger habe.
Fallen euch, sonst noch ein paar Fehler auf?

public abstract class StackQueueContainerImpl implements Container {

protected String[] container;
protected int size;

public StackQueueContainerImpl(int n){
container=new String[n];
size++;
}
public int capacity(){
return container.length;
}
public int size(){
return size;
}
public boolean isEmpty(){
return container.length==0;
}
public boolean isFull(){
return size<container.length;
}
public boolean putLast(String s){
if(isFull()) return false;
container[size]=s;
size++;
return true;
}

}
Java:
public class StackImpl extends StackQueueContainerImpl implements StackQueueContainer {
  
    public StackImpl(int n){
        super(n);
    }
    public String getLast(){
        if(isEmpty()) return null;
        String s= container[size-1];
        container[size-1]=null;
        size--;
        return s;
    }
  
}
Java:
public class QueueImpl extends StackQueueContainerImpl implements Queue{
  
    public QueueImpl(int n){
        super(n);
    }
    public String getFirst(){
        if(isEmpty()) return null;
        String s=container[0];
        container[0]=null;
        size--;
        return s;  
    }
}
Java:
public class DequeImpl extends QueueImpl implements Deque {
  
    public DequeImpl(int n){
        super(n);
    }
    public boolean putFirst(String s){
        if(isFull()) return false;
        container[0]=s;
        return true;
    }
    public String getLast(){
        if(isEmpty()) return null;
        String s= container[size-1];
        container[size-1]=null;
        size--;
        return s;
    }
}

Zu den Fragen, weiß ich auch noch nicht die Antwort.

2. In den Klassen DequeImpl und StackImpl hab ich die Methode getLast() implementiert. Hätte ich die doppelte Methodenimplementierung auch verhindern können? Oder, ist das so in Ordnung?
3. War es gut, dass ich die Attribute protected gemacht habe oder wäre private besser gewesen? Wäre das Array private, dann hätte ich in den Unterklassen nicht mehr drauf zugreifen können. Also ist protected hier richtig?
 

JavaIsTheBest

Bekanntes Mitglied
So, müsste es stimmen.

Java:
public boolean isEmpty(){
        return size==0;
    }
    public boolean isFull(){
        return size==container.length;
    }
 

Meniskusschaden

Top Contributor
2. In den Klassen DequeImpl und StackImpl hab ich die Methode getLast() implementiert. Hätte ich die doppelte Methodenimplementierung auch verhindern können? Oder, ist das so in Ordnung?
Da Java keine Mehrfachvererbung unterstützt, kannst du hier nicht alle Methoden vererben. Allerdings könntest du trotzdem doppelten Code reduzieren, indem du den Methodeninhalt nicht doppelt programmierst, sondern in eine andere mehrfach genutzte Klasse auslagerst. Das wahrscheinlich einfachste Beispiel wäre es, wenn die Stack- und Queue-Implementierungen intern einfach eine Dequeue-Instanz verwenden, um die Stack- bzw. Queue-Operationen abzubilden.
3. War es gut, dass ich die Attribute protected gemacht habe oder wäre private besser gewesen? Wäre das Array private, dann hätte ich in den Unterklassen nicht mehr drauf zugreifen können. Also ist protected hier richtig?
Meines Erachtens ist das in Ordnung.
 

JavaIsTheBest

Bekanntes Mitglied
Das size hab ich entfernt.
Java:
public StackQueueContainerImpl(int n){
        container=new String[n];
    }

Hätte ich die Methode getLast() auch static machen können. Oder findet ihr das keine gute Idee?
 

JavaIsTheBest

Bekanntes Mitglied
Was haltet ihr von dieser Implementierung?
Warum muss am Ende ein explizites return true? putLast(s) aus der Oberklasse liefert, doch schon ein true zurück.

Java:
public class DequeImpl2 extends DequeImpl {
   
    public DequeImpl2(int n){
        super(n);
    }
   
    public boolean putFirst(String s){
        if(s==null){
            return false;
        }
        super.putFirst(s);
        return true;
    }
    public boolean putLast(String s){
        if(s==null){
            return false;
        }
        super.putLast(s);
        return true;
    }

}
 

Anhänge

  • Unbenannt.PNG
    Unbenannt.PNG
    27,3 KB · Aufrufe: 20

mrBrown

Super-Moderator
Mitarbeiter
Warum muss am Ende ein explizites return true? putLast(s) aus der Oberklasse liefert, doch schon ein true zurück.
Du verwendest den return-Wert aber nicht ;) anstatt einfach true zu returnen (was den return-Wert der Oberklasse auch ignorieren würde) solltest du einfach #super.putLast returnen ;)


Hätte ich die Methode getLast() auch static machen können. Oder findet ihr das keine gute Idee?

Hättest du nicht machen können, du musst ja den letzte Wert EINER Instanz zurückgeben.
 

JavaIsTheBest

Bekanntes Mitglied
Sonst, stimmt der Code?

Java:
public class DequeImpl2 extends DequeImpl {
   
    public DequeImpl2(int n){
        super(n);
    }
   
    public boolean putFirst(String s){
        if(s==null){
            return false;
        }
        return super.putFirst(s);
       
    }
    public boolean putLast(String s){
        if(s==null){
            return false;
        }
        return super.putLast(s);
       
    }

}
 

JavaIsTheBest

Bekanntes Mitglied
Mal eine Frage, die nicht ganz zum Thema passt.

Java:
public boolean einzahlen(double betrag){
        if(super.einzahlen(betrag)){
            if(this.kontostand()>1000){
                return super.transfer(elternkonto, this.kontostand()-1000);
            }
        }
        else{
            return false;
        }
        return false;
    }

Wird in dem ersten if-Statement nur der Rückgabewert der Methode super.einzahlen(betrag) geprüft oder auch aufgerufen/ausgeführt?
 

mrBrown

Super-Moderator
Mitarbeiter
Mal eine Frage, die nicht ganz zum Thema passt.

Java:
public boolean einzahlen(double betrag){
        if(super.einzahlen(betrag)){
            if(this.kontostand()>1000){
                return super.transfer(elternkonto, this.kontostand()-1000);
            }
        }
        else{
            return false;
        }
        return false;
    }

Wird in dem ersten if-Statement nur der Rückgabewert der Methode super.einzahlen(betrag) geprüft oder auch aufgerufen/ausgeführt?
Kann der Rückgabewert geprüft werden, ohne dass die Methode ausgeführt wird? ;)
 

Neue Themen


Oben