# Schnittstellen



## JavaIsTheBest (14. Jun 2016)

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



Spoiler: Container





```
public interface Container {
    public int size();
    public boolean isEmpty();
    public boolean isFull();
}
```






Spoiler: StackQueueContainer





```
public interface StackQueueContainer extends Container{
public String putLast(String s);
}
```






Spoiler: Stack





```
public interface Stack extends StackQueueContainer{
    public String getLast();
}
```






Spoiler: Queue





```
public interface Queue extends StackQueueContainer {
    public String getFirst();
}
```






Spoiler: Deque





```
public interface Deque extends Stack, Queue {
    public boolean putFirst(String s);
}
```


----------



## fhoffmann (14. Jun 2016)

Warum gibt putLast einen String zurück und putFirst einen boolean?


----------



## JavaIsTheBest (14. Jun 2016)

Stimmt, es müssen beide Methoden einen boolean zurückgeben. stimmt aber der Rest?


----------



## JStein52 (14. Jun 2016)

Ja


----------



## JavaIsTheBest (14. Jun 2016)

Und was haltet ihr von meiner Implementierung?



Spoiler: StackQueueContainerImpl 





```
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;
    }

}
```






Spoiler: StackImpl





```
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;
    }
  
}
```






Spoiler: QueueImpl





```
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;  
    }
}
```






Spoiler: DequeImpl





```
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?


----------



## mrBrown (14. Jun 2016)

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 (15. Jun 2016)

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?



Spoiler: StackQueueContainerImpl





```
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;
    }

}
```






Spoiler: QueueImpl





```
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;   
    }
}
```






Spoiler: StackImpl





```
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;
    }
   
}
```






Spoiler: DequeImpl





```
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;
    }
}
```


----------



## Meniskusschaden (15. Jun 2016)

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.


----------



## JavaIsTheBest (15. Jun 2016)

Wo mach ich das?


----------



## Meniskusschaden (15. Jun 2016)

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 (15. Jun 2016)

JavaIsTheBest hat gesagt.:


> 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 (17. Jun 2016)

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?



Spoiler: StackQueueContainerImpl



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;
   }

}





Spoiler: StackImpl





```
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;
    }
  
}
```






Spoiler: QueueImpl





```
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;  
    }
}
```






Spoiler: DequeImpl





```
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?


----------



## mrBrown (17. Jun 2016)

#isEmpty und #isFull sind noch falsch


----------



## JavaIsTheBest (17. Jun 2016)

So, müsste es stimmen.


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


----------



## Meniskusschaden (17. Jun 2016)

Du inkrementierst size im Konstruktor. Dadurch hätte ein leerer Container die Größe 1.


----------



## Meniskusschaden (17. Jun 2016)

JavaIsTheBest hat gesagt.:


> 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.


JavaIsTheBest hat gesagt.:


> 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 (17. Jun 2016)

Das size hab ich entfernt.

```
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 (18. Jun 2016)

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.


```
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;
    }

}
```


----------



## mrBrown (18. Jun 2016)

JavaIsTheBest hat gesagt.:


> 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 




JavaIsTheBest hat gesagt.:


> 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 (18. Jun 2016)

Sonst, stimmt der Code?



Spoiler: DequeImpl2





```
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);
       
    }

}
```


----------



## mrBrown (18. Jun 2016)

Ja


----------



## JavaIsTheBest (18. Jun 2016)

Mal eine Frage, die nicht ganz zum Thema passt.


```
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 (18. Jun 2016)

JavaIsTheBest hat gesagt.:


> Mal eine Frage, die nicht ganz zum Thema passt.
> 
> 
> ```
> ...


Kann der Rückgabewert geprüft werden, ohne dass die Methode ausgeführt wird?


----------

