# Modellierung, vererbung,



## Noob1234_1234 (14. Jan 2020)

Hallo zusammen, 
ich soll einen ContainerTerminal modellieren. Dieser besteht insgesamt aus Containerstapeln und einem Kran, der Stapel wiederum aus 2 Arten von Container (mit ihren Eigenschaften / Vererbung) . Ich hab glaub ich soweit alles in den Bausteinen umgesetzt, aber mir ist beim Kran und dem Stappel nicht klar, wie diese interagieren sollen.  

Die Aufgabe sagt mir :
"Ein Containerstapel besteht aus keinem, einem, oder mehreren Containern und es ist egal wie viele Stappel es gibt bzw erzeugt werden". Aber mich verwirrt jetzt der Kran, denn der soll :
Mit Hilfe des Krans können Container von einem Ursprungsstapel zu einem Zielstapel bewegt werden. Wichtig ist, dass der Kran nur Containertransporte durchzuführen kann, die im Rahmen seiner Fähigkeiten liegen, d.h. unter Beachtung der maximalen Traglast und Hubhöhe. Auch ist der Kran nicht fähig, mehrere Container gleichzeitig zu transportieren. Der Containertransport geschieht in vier Schritten:
1. Positioniere Kran vor Ursprungsstapel
2. Entnehme obersten Container („pick“)
3. Positioniere Kran vor Zielstapel
 4. Lege zuvor aufgenommenen Container zuoberst ab („place“)

Das alles klingt doch sehr nach einem Stack oder ? Ich bin im Moment soweit, dass ich das habe :

```
import java.util.ArrayList;
import java.util.List;

public class Stack<Container> {

    private int containerStackID;
    private static int firstContainerID = 0;
    private final List<Container> stackElements;

    public void createContainerStackID() {
        containerStackID = ++firstContainerID;
    }

    public int getContainerStackID() {
        return containerStackID;
    }

    public Stack() {
        createContainerStackID();
        stackElements = new ArrayList<>();
    }

    public void push(Container element) {
        stackElements.add(element);
    }

    public boolean isEmpty() {
        return stackElements.isEmpty();
    }

    public Container pop() {
        if (isEmpty()) {
            throw new EmptyStackException("Der Stack ist leer!");
        } else {
            int lastIndex = stackElements.size() - 1;
            Container lastElement = stackElements.get(lastIndex);
            stackElements.remove(lastIndex);
            return lastElement;
        }
    }

    @Override
    public String toString() {
        return "Stack [stackElements=" + stackElements + "]+ conatainerStackID ";
    }

    public void clear() {
        stackElements.clear();
    }

}
```
Hier dachte ich, dass es sich um den Containerstappel handelt, aber kann es sein, dass ich die Klasse gar nicht brauche, da der Kran diese ganzen Methoden braucht? 

hier noch der Kran : 

```
public class Kran {
    
    private Container40ft container40ft;
    private Container40ftHC container40ftHC;
    private static final int maxHeight = 2438; // 160 Fuß entsprechen 2438,4 cm
    private static final int maxloadCapacity = 30; // Tonnen

    public static int getMaxheight() {
        return maxHeight;
    }

    public static int getMaxloadcapacity() {
        return maxloadCapacity;
    }

}
```


----------



## Javinner (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> dass der Kran nur Containertransporte durchzuführen kann, die im Rahmen seiner Fähigkeiten liegen, d.h. unter Beachtung der maximalen Traglast und Hubhöhe


Da es paar verschiedene Krans gibt, welche sich in Hubhöhe, Reichweite und Kraft unterscheiden, gilt es, diese Eigenschaften dem jeweiligen Kran zu "geben".
Eine Möglichkeit wäre es, ein Interface Kran mit Methoden wie

maxLiftPower() : double
maxLiftHight() : double
maxReach() : double
einzuführen und dann jede implementierende Klasse hart-codieren, wie du es bereits bei deinem Kran gemacht hast. Hat den Vorteil, dass jeweilige Klasse nur für sich geändert werden kann.

```
interface Crane
{
   public double maxLiftPower();
   public double maxLiftHight();
   public double maxReach();
}

class LittleCrane implements Crane
{
    private final double liftPower = 10;
    private final double liftHight = 10;
    private final double maxReach = 10;
   
    public double maxLiftPower()
    {
        return this.liftPower;
    }
    public double maxLiftHight()
    {
        return this.liftHight;
    }
    public double maxReach()
    {
        return this.maxReach;
    }

}
```
Man kann aber auch eine Klasse Kran erstellen, dabei ist eben die Gefahr vorhanden, dass falsche Werte an ein Kran übergeben werden können.

```
class Crane
{
    private final double liftPower;
    private final double liftHight ;
    private final double maxReach;

    Crane(double lift, double hight, double power)
    {
          //Werte übertragen
    }

    public double maxLiftPower()
    {
        return this.liftPower;
    }
    public double maxLiftHight()
    {
        return this.liftHight;
    }
    public double maxReach()
    {
        return this.maxReach;
    }
}
```


----------



## Noob1234_1234 (14. Jan 2020)

Javinner hat gesagt.:


> Da es paar verschiedene Krans gibt, welche sich in Hubhöhe, Reichweite und Kraft unterscheiden, gilt es, diese Eigenschaften dem jeweiligen Kran zu "geben".
> Eine Möglichkeit wäre es, ein Interface Kran mit Methoden wie
> 
> maxLiftPower() : double
> ...



in der Aufgabe wird festgelegt, dass es nur einen Kran gibt und er hat die Fähigkeit entweder die Container vom Ursprungsstapel zu nehmen und zu einem Zielstappel zu bringen, aber wie leg ich das fest bzw wie setz ich diese Vorgaben um? Brauche ich eine Stappelklasse für die Container?(wenn ja welche datenstruktur nutzt sie und wie sieht sie aus) und vor allem wie setz ich es um, dass ich dem Kran 2 integer mitgebe und er automatisch, weiß, dass sich der erste Integerwert auf stappel 1 bezieht und der 2. wert eben auf den anderen Stappel ?


----------



## mihe7 (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Das alles klingt doch sehr nach einem Stack oder ?


Stack ist das englische Wort für Stapel  



Noob1234_1234 hat gesagt.:


> er hat die Fähigkeit entweder die Container vom Ursprungsstapel zu nehmen und zu einem Zielstappel zu bringen, aber wie leg ich das fest


Mit Hilfe einer Methode, z. B. `void transportContainer(Stapel origin, Stapel destination)`.


----------



## Noob1234_1234 (14. Jan 2020)

mihe7 hat gesagt.:


> Stack ist das englische Wort für Stapel
> Damit wollte ich eigentlich erfragen, ob ich einen Stack als Datenstruktur nutzen sollte oder eben nicht, Wenn nicht, was dann ?
> 
> Mit Hilfe einer Methode, z. B. `void transportContainer(Stapel origin, Stapel destination)`.


Aber wie sollte denn die Stappelklasse aussehen? Ist meine Umsetzung oben gut oder nicht gut. Ich hab ja im Prinzip nur quasi einen Stack für Container geschrieben oder nicht? Brauche ich jetzt noch zusätzlich eine Klasse mit Konstruktor für die Containerstappel


----------



## mihe7 (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Aber wie sollte denn die Stappelklasse aussehen?


Verwende doch einfach java.util.Stack. Dann ändert sich die Methodensignatur zu `transportContainer(Stack<Container> origin, Stack<Container> destination);`


----------



## mihe7 (14. Jan 2020)

Nachtrag: wie ich gerade lese, wird es die Methode so nicht geben, da die Transportschritte einzeln durchzuführen sind.


----------



## Noob1234_1234 (14. Jan 2020)

mihe7 hat gesagt.:


> Nachtrag: wie ich gerade lese, wird es die Methode so nicht geben, da die Transportschritte einzeln durchzuführen sind.


Muss soweit ich weiß nicht, es gilt nur die Bedingungen zu beachten, dass der zu transportierende Container nicht schwerere als die Traglast des Krans ist und dass der Stapel nicht die Höhe des Krans überschreitet. Also müsste es doch so irgendwie aussehen oder ?

```
public class Kran {

    private Container40ft container40ft;
    private Container40ftHC container40ftHC;
    private static final int maxHeight = 2438; // 160 Fuß entsprechen 2438,4 cm
    private static final int maxloadCapacity = 30;

    public static int getMaxheight() {
        return maxHeight;
    }

    public static int getMaxloadcapacity() {
        return maxloadCapacity;
    }

    public static void transportContainer(Stack<Container> origin, Stack<Container> destination) {
        if (Kran.getMaxloadcapacity() > origin.getContainer.getWeight()) {
            Container origin = pop();
            destination.push(origin);
        }
    }

}
```


----------



## Noob1234_1234 (14. Jan 2020)

Aber es bleibt immernoch die Frage wie ich die Containerstappelklasse implementiere, denn ich muss ja irgendwie an die Container kommen, um Zugriff auf deren Gewicht zu kriegen, aber wie mach ich das ?


----------



## temi (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> ```
> public class Kran {
> private Container40ft container40ft;
> private Container40ftHC container40ftHC;
> ```



Wozu sollte denn ein Kran einen (oder zwei) Container beinhalten?


----------



## mihe7 (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Muss soweit ich weiß nicht, es gilt nur die Bedingungen zu beachten, dass der zu transportierende Container nicht schwerere als die Traglast des Krans ist und dass der Stapel nicht die Höhe des Krans überschreitet.


Das musst Du wissen. Ich habe nur gelesen:


Noob1234_1234 hat gesagt.:


> Der Containertransport geschieht in vier Schritten:



Also, jetzt gehen wir mal zurück auf Anfang - ohne Code. Wie sieht denn Dein Modell im Diagramm aus?


----------



## temi (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Aber es bleibt immernoch die Frage wie ich die Containerstappelklasse implementiere, denn ich muss ja irgendwie an die Container kommen, um Zugriff auf deren Gewicht zu kriegen, aber wie mach ich das ?



Grob soll der Sta*p*el der Aufgabe nach so aussehen:


```
public class Stapel {
 
    public Container pick() {
     
    }
 
    public void place(Container container) {
     
    }
}
```

Edit:

"pick()" und "place()" könnten allerdings auch Methoden des Kranes sein. Die Aufgabe, wie oben beschrieben, lässt es offen, wie die Methoden des Stapels heißen, um den obersten Container zu entfernen, bzw. hinzuzufügen.


----------



## Noob1234_1234 (14. Jan 2020)

temi hat gesagt.:


> Wozu sollte denn ein Kran einen (oder zwei) Container beinhalten?


Jap hast Recht die braucht er net. Diese Eigenschaft sollte in eine Klasse, die die Stappel erzeugt und verwaltet oder ?


----------



## temi (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Stappel



Stapel

Ich krieg da Schwindelanfälle, wenn ich das lese...


----------



## temi (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Diese Eigenschaft sollte in eine Klasse, die die Stappel erzeugt und verwaltet oder ?



Nicht so, wie oben in "Kran" gezeigt. Es handelt sich ja nicht nur um einen oder zwei Container, sondern um "beliebig" viele Container.


----------



## Noob1234_1234 (14. Jan 2020)

mihe7 hat gesagt.:


> Das musst Du wissen. Ich habe nur gelesen:
> 
> 
> Also, jetzt gehen wir mal zurück auf Anfang - ohne Code. Wie sieht denn Dein Modell im Diagramm aus?


Also die Modellierung ist eigentlich relativ simple :
Ein Container-Terminal besitzt genau einen fahrbaren Kran sowie einen oder mehrere
Containerstapel. Containerstapel sind beginnend mit 0 fortlaufend nummeriert; Integer genügt,
um die Stapelnummern darzustellen. Ein Containerstapel besteht aus keinem, einem, oder mehreren
Containern. 
Für die Container gilt : 
Man unterscheidet zwei Arten von Containern: 40-Fuß-Container (Kurzschreibweise: 40ft) sowie 40-Fuß-High-Cube-Container ( Kurzschreibweise: 40ftHC). Dabei bezeichnet 40 Fuß1 die Länge der Container. „High Cube“-Container sind höher im Vergleich zu regulären 40-Fuß-Containern. Erstere haben eine Höhe von 9 Fuß und 6 Zoll, letztere haben eine Höhe von nur 8
Fuß und 6 Zoll. Ein Container in unserem vereinfachten Modell besitzt neben seinem Typ folgende Eigenschaften: Länge, Höhe, Gewicht, sowie eine eindeutige Identifizierungsnummer. Das Gewicht beinhaltet das Eigengewicht des Containers sowie die im Container enthaltene Fracht. Breite und weitere Eigenschaften sollen vernachlässigt werden.

Ich denk mal bei den Containern kann man nicht viel falsch machen. Ich hab eine allgemeine Container Klasse und lasse die beiden speziellen Arten davon erben und statte sie mit einem Konstruktor jeweils aus, der ihnen eine int und ein gewicht mitgibt


----------



## mihe7 (14. Jan 2020)

...


----------



## Noob1234_1234 (14. Jan 2020)

mihe7 hat gesagt.:


> Das musst Du wissen. Ich habe nur gelesen:
> 
> 
> Also, jetzt gehen wir mal zurück auf Anfang - ohne Code. Wie sieht denn Dein Modell im Diagramm aus?


Was meinst du mit Modell im Diagramm?


----------



## Noob1234_1234 (14. Jan 2020)

temi hat gesagt.:


> Grob soll der Sta*p*el der Aufgabe nach so aussehen:
> 
> 
> ```
> ...


Braucht die ganze Klasse den Stack oder erstellt sich der Stack immer nur im Konstruktor bzw in lokalen Methoden?


----------



## Noob1234_1234 (14. Jan 2020)

temi hat gesagt.:


> Grob soll der Sta*p*el der Aufgabe nach so aussehen:
> 
> 
> ```
> ...


Weil beim placen der Container muss der Container ja durch irgendeine Datenstruktur gespeichert werden und das ist ja dann der Stack ?


----------



## temi (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Weil beim placen der Container muss der Container ja durch irgendeine Datenstruktur gespeichert werden und das ist ja dann der Stack ?



Ein Stack wäre eine gut geeignete Klasse dafür.


----------



## Noob1234_1234 (14. Jan 2020)

So in die Richtung sollte es dann gehen oder ?

```
ublic class ContainerStack {

    private Container40ft container40ft;
    private Container40ftHC container40ftHC;

    Stack<Container> stack = new Stack<>();

    public Container pick() {
        Container container = stack.pop();
        return container;
    }

    public void place(Container container) {
        stack.push(container);
    }

}
```


----------



## temi (14. Jan 2020)

Wozu braucht denn der ContainerStack die beiden einzelnen Container?


----------



## mihe7 (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Was meinst du mit Modell im Diagramm?


Muss man hier alles selber machen?



Hier fehlen noch Methoden. Wo und welche?


----------



## temi (14. Jan 2020)

@mihe7 du hast da einen kleinen Fehler:


Noob1234_1234 hat gesagt.:


> Ein Containerstapel besteht aus *keinem*, einem, oder mehreren Containern


----------



## mihe7 (14. Jan 2020)

temi hat gesagt.:


> @mihe7 du hast da einen kleinen Fehler:


Danke für den Hinweis, habs korrigiert. (EDIT: und jetzt auch noch richtig )


----------



## temi (14. Jan 2020)

mihe7 hat gesagt.:


> Danke für den Hinweis, habs korrigiert. (EDIT: und jetzt auch noch richtig )


Ich bin ausdrücklich kein UML-Spezialist, aber müsste es nicht "0---->*" sein?


----------



## Noob1234_1234 (14. Jan 2020)

mihe7 hat gesagt.:


> Muss man hier alles selber machen?
> 
> Anhang anzeigen 12884
> 
> Hier fehlen noch Methoden. Wo und welche?



Wenn ich es richtig sehe, fehlen nur die Methoden vom Kran. Darf ich fragen, wie du dieses Diagramm erstellt hast ? 
Der Kran muss doch auch Zugriff auf den Stapel haben oder ?  Den der Kran muss die Container ja bewegen und wie gesagt er kann das nur wenn der Container nicht schwerer als seine Traglast ist. Mit der 2. Bedingung tue ich mir schwer. Ich denke man merkt, dass ich kein Muttersprachler in der deutschen Sprache bin. Aber vielleicht kann mir wer das erläutern:

"
Ein Kran besitzt eine maximale Hubhöhe. Das ist die Höhe, die ein theoretisch vollkommen flacher Gegenstand der Höhe 0 angehoben werden könnte. Die tatsächliche Hubhöhe muss um die Höhe des angehobenen Gegenstands vermindert werden. Beträgt die maximale Hubhöhe 80 Fuß, so ergibt sich für einen 10 Fuß hohen Container eine tatsächlich erreichbare Hubhöhe von 70 Fuß. Falls die tatsächlich erreichbare Hubhöhe geringer als die Höhe des Zielstapels ist, ist es dem Kran nicht möglich, den Container auf dem Zielstapel zu platzieren. Der Container wird in diesem Fall gar nicht erst vom Ursprungsstapel entnommen. Stellen Sie die maximale Hubhöhe des Krans unveränderlich auf 160 Fuß ein. " Die Einheiten hab ich umgerechnet in cm


----------



## Noob1234_1234 (14. Jan 2020)

```
import java.util.Stack;

public class ContainerStack {

    private int containerStackID;
    private static int firstContainerID = 0;

    Stack<Container> stack = new Stack<>();

    public void createContainerStackID() {
        containerStackID = ++firstContainerID;
    }

    public int getContainerStackID() {
        return containerStackID;
    }

    public Container pick() {
        Container container = stack.pop();
        return container;
    }

    public void place(Container container) {
        stack.push(container);
    }

    public ContainerStack(Container container) {
        createContainerStackID();
        place(container);
    }
}
```

Ich glaube so kann die Stapel Klasse auch nicht stimmen oder ? Muss Im Konstruktor jedes Mal eine neuer stack erstellt werden oder passt es so ? Ich will ja am Ende mindestens 3 Stapel im TerminalContainer haben, auf denen man die Container ablegen kann. Also sollten es auch 3 unterschiedliche Stacks zum speichern sein, aber ich bin mir nicht sicher, ob meine Implementierung, das so gewährleistet


----------



## mrBrown (14. Jan 2020)

temi hat gesagt.:


> Ich bin ausdrücklich kein UML-Spezialist, aber müsste es nicht "0---->*" sein?


1 dürfte passen, es ist ja *ein* Container-Stapel, der aus X Containern besteht.

EDIT: Wobei Container die bewegt werden, natürlich zu keinem Stapel gehören, vielleicht doch 0...


----------



## temi (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Ein Kran besitzt eine maximale Hubhöhe. Das ist die Höhe, die ein theoretisch vollkommen flacher Gegenstand der Höhe 0 angehoben werden könnte. Die tatsächliche Hubhöhe muss um die Höhe des angehobenen Gegenstands vermindert werden. Beträgt die maximale Hubhöhe 80 Fuß, so ergibt sich für einen 10 Fuß hohen Container eine tatsächlich erreichbare Hubhöhe von 70 Fuß. Falls die tatsächlich erreichbare Hubhöhe geringer als die Höhe des Zielstapels ist, ist es dem Kran nicht möglich, den Container auf dem Zielstapel zu platzieren. Der Container wird in diesem Fall gar nicht erst vom Ursprungsstapel entnommen. Stellen Sie die maximale Hubhöhe des Krans unveränderlich auf 160 Fuß ein. " Die Einheiten hab ich umgerechnet in cm



Was verstehst du denn daran nicht? Du musst halt vor dem Abladen/Absetzen prüfen, ob der Kran die Höhe des Stapels überhaupt erreichen kann.


----------



## temi (14. Jan 2020)

mrBrown hat gesagt.:


> 1 dürfte passen, es ist ja *ein* Container-Stapel, der aus X Containern besteht.


Ah, OK. Wodurch wird dann ausgedrückt, dass es kein, ein oder mehrere Behälter sein kann?

Edit: Vermutlich der *, der ja auch 0 entsprechen kann?


----------



## Noob1234_1234 (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> ```
> import java.util.Stack;
> 
> public class ContainerStack {
> ...



Und jetzt wo ich so darüber nachdenke, weiß ich auch net, ob die place methode in den Konstruktor gehört. Die Aufgabe gibt ja nicht her, ob schon stapel mit Containern vorhanden sind, aber es muss ja eigentlich so sein, denn der Kran oder das Terminal kann sie ja schließlich nicht herzaubern


----------



## mrBrown (14. Jan 2020)

temi hat gesagt.:


> Ah, OK. Wodurch wird dann ausgedrückt, dass es kein, ein oder mehrere Behälter sein kann?


Das Sternchen auf der anderen Seite, `ContainerStapel -1--besteht aus--*-> Container` liest sich ja als "Ein ContainerStapel besteht aus beliebig vielen Containern"


----------



## temi (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Ich will ja am Ende mindestens 3 Stapel im TerminalContainer haben, auf denen man die Container ablegen kann.



Es ist ja nicht festgelegt, wieviele Containerstapel am ContainerTerminal stehen. Deshalb wirst du in ContainerTerminal auch eine flexible Möglichkeit benötigen mehrere Containerstapel zu haben. List<ContainerStack> würde sich da anbieten.

Da die Liste indexiert ist, könnte dieser Index auch gleich als Identifikation für die Stapel verwendet werden.


----------



## Noob1234_1234 (14. Jan 2020)

temi hat gesagt.:


> Was verstehst du denn daran nicht? Du musst halt vor dem Abladen/Absetzen prüfen, ob der Kran die Höhe des Stapels überhaupt erreichen kann.


Also sollte ich in der Stapel klasse eine Methode haben, die die Größe des Stapels berechnet, um es zu vereinfachen ?

Aber in der Kran Klasse versteh ich dann nicht, wie ich denn über die Stappel auf die Container zugreifen kann

```
ublic class Crane {

    private static final int maxHeight = 2438; // 160 Fuß entsprechen 2438,4 cm
    private static final int maxloadCapacity = 30; // in Tonnen
    private ContainerStack containerstack;

    public static int getMaxheight() {
        return maxHeight;
    }

    public static int getMaxloadcapacity() {
        return maxloadCapacity;
    }

    public static void transportContainer(ContainerStack origin, ContainerStack destination) {
        if (Crane.getMaxloadcapacity() > origin.getContainer???? { // Wie greife ich auf die Container zu
            Container origin = origin.destination.push(origin);
        }
    }

}
```

Edit : Ich weiß inzwischen wie ich darauf zugreife, aber ich weiß nicht wie ich die Höhe vom Stappel bestimmen soll. Eigentlich hätte ich ja stack.size * Höhe gesagt, aber die Container haben keine einheitliche Höhe

Edit : Ich bin dumm und die Container haben eine einheitliche Größe. habs verwechselt mit der Länge


----------



## temi (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Aber in der Kran Klasse versteh ich dann nicht, wie ich denn über die Stappel auf die Container zugreifen kann



origin.pick() nimmt den obersten Container des Ursprungsstapels...

Edit: Allerdings hast du hier das Problem, dass du vor dem Nehmen prüfen musst, ob du den Container überhaupt nehmen kannst. Wir kennen die Aufgabe nicht. Gibt es genauere Angaben, welche Methoden der Stapel hat und wie sie benannt sind?


----------



## temi (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> aber ich weiß nicht wie ich die Höhe vom Stappel bestimmen soll.



Spendier dem ContainerStack eine Methode getHeight(). In dieser addierst du die Höhen der sich auf dem Stapel befindlichen Container.


----------



## mihe7 (14. Jan 2020)

temi hat gesagt.:


> Ich bin ausdrücklich kein UML-Spezialist, aber müsste es nicht "0---->*" sein?


Wenn, dann 0..1 --> *   Die genaue Bedeutung müsste ich jetzt auch erst nachlesen. Die 1 soll auf jeden Fall aussagen, dass ein Container sich in einem ContainerStack befinden muss


----------



## mihe7 (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Darf ich fragen, wie du dieses Diagramm erstellt hast ?


Klar, mit Umlet (www.umlet.com).

Den Rest diskutiert ihr eh schon fleißig


----------



## Noob1234_1234 (14. Jan 2020)

Also ich glaube, dass ich soweit die Grundbausteine für die Modellierung habe.  So sieht jetzt mein Kran aus(siehe unten), aber ich hab gerade in der Aufgabe weitergelesen, dass ich eine Textdatei mit 1. <Typ >;<Id >;< Gewicht >;< Stapel > und 2. <Ursprung >;< Ziel > schreiben muss. Der Path der Textdatei soll der Kommandozeile übergeben werden und jetzt hab ich das Problem, dass das Token <Ursprung > für die Ursprungsstapel-Numme steht und wieder eine positive int-Zahl inklusive 0 ist . Das Token <Ziel > steht für die Zielstapel-Nummer und ist wieder eine positive int-Zahl inklusive 0. Also werden der Methoden Zahlen übergeben und keine Container 


```
public class Crane {

    private static final int maxHeight = 2438; // 160 Fuß entsprechen 2438,4 cm
    private static final int maxloadCapacity = 30; // in Tonnen

    public static int getMaxheight() {
        return maxHeight;
    }

    public static int getMaxloadcapacity() {
        return maxloadCapacity;
    }

    public static void transportContainer(ContainerStack origin , ContainerStack destination) {
        if (Crane.getMaxloadcapacity() >= origin.getContainerWeight()
                && Crane.getMaxheight() >= (Crane.getMaxheight() - destination.calculateContainerStackHeight())) {

            Container c = origin.pick();
            destination.place(c);
        }
    }
}
```


----------



## mihe7 (14. Jan 2020)

Vielleicht wäre das folgende Teilmodell besser geeignet?


----------



## Noob1234_1234 (14. Jan 2020)

Also ich bin wieder zurück und es gibt noch 2 Sachen bisher, die mich grundlegend irritieren. Also erstens soll der Kran zwei Zahlen (Integer entgegennehmen) und anhand von diesen die jeweiligen Stapel finden. Ich hab zwar in der Stapelklasse die Methode, die automatisch hochzählt wenn ein neuer Stapel erzeugt wird und entsprechend einen getter dafür, aber wie setz ich das im Kran um?

und seh ich es richtig, dass meine TerminalContainer Klasse die Hauptklasse inklusive main Methode ist ?


----------



## mihe7 (14. Jan 2020)

Poste doch mal die ganze Aufgabe, da fehlen mir zu viele Infos. Bislang haben wir ja nur ein grobes Modell, mir fehlt z. B., was zur Laufzeit überhaupt gemacht werden soll.


----------



## Noob1234_1234 (14. Jan 2020)

mihe7 hat gesagt.:


> Poste doch mal die ganze Aufgabe, da fehlen mir zu viele Infos. Bislang haben wir ja nur ein grobes Modell, mir fehlt z. B., was zur Laufzeit überhaupt gemacht werden soll.



Ihr Programm nimmt als erstes und einziges Kommandozeilenargument einen Pfad auf eine Textdatei entgegen. Verwenden Sie die Methode readFile der Klasse Terminal, um den Inhalt einer Datei zu lesen. Diese Methode hat als Rückgabewert ein String [], das die einzelnen Zeilen der Datei path enthält. Diese Datei beschreibt ein Container-Terminal wie beispielsweise in Abb. 0.1 dargestellt. Diese Datei besteht aus zwei Bereichen. Der erste Bereich beschreibt den initialen Aufbau eines Container-
Terminals. Der zweite Bereich beschreibt Containertransporte, die der Kran, ausgehend von dem initialen Aufbau, ausführen soll. Beide Bereiche sind durch eine Zeile mit dem Inhalt -- voneinander separiert. *Hierbei können Sie nicht davon ausgehen, dass gegebene Eingabedateien immer genau nach den gegebenen Spezifikationen aufgebaut sind, folglich müssen Sie diese sowohl auf Semantik- als auchauf Syntaxfehler überprüfen. Eingabedateien, welche gegen die Spezifikation für Container und das Terminal verstoßen oder nicht nach untenstehender Syntaxspezifikation aufgebaut sind, führen zum Beenden des Programms, nachdem eine passende Fehlermeldung ausgegeben wurde. *(Also hier muss ich die Eingabedateien irgendwie mit regex matcher und pattern überprüfen oder? )

Der erste Bereich enthält beliebig viele Zeilen. Jede Zeile beschreibt einen Container und seinen Lagerort. Befinden sich zwei Container im selben Containerstapel, liegt der Container mit kleinerer Zeilennummer unter dem Container mit größerer Zeilennummer. Jede Zeile ist folgendermaßen aufgebaut:
<Typ >;<Id >;< Gewicht >;< Stapel >
Das Token <Typ > steht für den Containertyp und ist dabei entweder 40 ft oder 40 ftHC. Das Token <Id > steht für Container-Id und ist eine positive int-Zahl. Das Token <Gewicht > steht für das Containergewicht und ist eine positive int-Zahl. Das Token <Stapel >steht für die Containerstapel-Nummer und ist eine positive int-Zahl inklusive 0.  (Für den Typ ein Enum? aber wie geht das mit Zahlen?)

Der zweite Bereich enthält beliebig viele Zeilen. Jede Zeile beschreibt einen Containertransport des Krans, bestehend aus den vier Teilschritten (1) positionieren vor Ursprungsstapel, (2) aufnehmen, (3) positionieren vor Zielstapel, (4) ablegen. Jede Zeile ist folgendermaßen aufgebaut:
<Ursprung >;< Ziel >
Das Token <Ursprung > steht für die Ursprungsstapel-Nummer und ist wieder eine positive int-Zahl inklusive 0. Das Token <Ziel > steht für die Zielstapel-Nummer und ist wieder eine positive int-Zahl inklusive 0. (Hier habe ich das Problem mit den Zahlen)

Wie soll die Terminalklasse denn aussehen, ich hab es gerade versucht, aber ich hab wirklich keine Ahnung. Auf jeden Fall besitzt diese Klasse ja einen Kran und den habe ich instanziert, aber wie ich mit den Stappeln weiter vorgehen soll weiß ich nicht


----------



## Noob1234_1234 (14. Jan 2020)

```
import java.util.Stack;

public class ContainerStack {

    private Container container;
    private int containerStackID;
    private static int firstContainerID = 0;
    private int ContainerStackHeight;

    Stack<Container> stack = new Stack<>();

    public int calculateContainerStackHeight() {
        ContainerStackHeight = stack.size() * 1219;
        return ContainerStackHeight;
    }

    public int getContainerWeight() {
        return container.getWeight();
    }

    public ContainerTyp getConTainerTyp() {
        return container.getContainertyp();
    }

    public void createContainerStackID() {
        containerStackID = ++firstContainerID;
    }

    public int getContainerStackID() {
        return containerStackID;
    }

    public Container pick() {
        Container container = stack.pop();
        return container;
    }

    public void place(Container container) {
        stack.push(container);
    }

    public ContainerStack(Container container) {
        createContainerStackID();
        place(container);
    }

    public String toString() {
        return String.format("%s;%s;%s;%s", container.getContainertyp(), container.getId(), container.getWeight(),
                containerStackID);
    }

    public static void main(String[] args) {
        ContainerStack cs = new ContainerStack(new Container40ft(ContainerTyp.A, 1, 1));
        ContainerStack cs1 = new ContainerStack(new Container40ft(ContainerTyp.B, 1, 1));
        System.out.println(cs);
        //System.out.println(cs1);
    }
}
Ich bekomme beim testen der toString eine NullpointerException, aber wieso?
```

Hier die ContainerKlasse

```
public class Container {
    protected int length;
    protected static final int height = 1219; // in Fuß (umgerechent = 1219,2)
    protected int id;
    protected int weight;
    protected ContainerTyp containertyp;

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    public static int getHeight() {
        return height;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public ContainerTyp getContainertyp() {
        return containertyp;
    }

}
```

Und hier die 2 Klassen, die erben 
1.

```
public class Container40ft extends Container {
    private static final int lenght = 259; // 8 Fuß 6 Zoll sind umgerechnet 259.08 cm
    private final ContainerTyp containertyp;

    Container40ft(ContainerTyp container, int id, int weight) {
        this.containertyp = container;
        super.id = id;
        super.weight = weight;
    }

    public int getLenght40ft() {
        return lenght;
    }

}
```

2.
public class Container40ftHC extends Container {
    private static final int lenght = 289; // 9 Fuß 6 Zoll sind umgerechent ca 289.56 cm
    private ContainerTyp containertyp;

    Container40ftHC(ContainerTyp containertyp, int id, int weight) {
        this.containertyp = containertyp;
        super.id = id;
        super.weight = weight;
    }

    public int getLenght40ftHC() {
        return lenght;
    }
}

Ich erstelle doch oben bei der test main methode einen neuen Container und will diesen printen. In den 2 erbenden Containern selbst werden doch die Werte, die mitgegeben werden, in der allgemeinen Container Klasse gespeichert  (durch den Aufruf super.), aber wieso klappt das nicht ? Ich krieg eine Nullpointer


----------



## mihe7 (14. Jan 2020)

Aha, mit #45 wird endlich ein Schuh draus. 



Noob1234_1234 hat gesagt.:


> Ich krieg eine Nullpointer


Ja, was soll denn container sein?


----------



## Noob1234_1234 (14. Jan 2020)

mihe7 hat gesagt.:


> Aha, mit #45 wird endlich ein Schuh draus.
> 
> 
> Ja, was soll denn container sein?


in dem Fall war es ein Enum, dass aus nur 40ft und 40ftHC besteht, aber das mit dem Enum klappt irgendwie nicht und ich bin seit stunden am Testen und bin mir sicher, dass meine Datenkapselung scheiße ist. Wie greif ich in meiner Modellierung bitte auf die entsprechenden Attribute der anderen Klassen zu ?

Am Bsp kran und Stapel: So funktioniert die Methode, aber so wie oben mit den Bedingugen, die eigentlich auf die Werte von Container greifen sollten, klappt es nicht? Was mach ich falsch bei der Datenkapselung 


```
public void transportContainer(ContainerStack origin, ContainerStack destination) {

            Container c = origin.pick();
            destination.place(c);
        }
```


----------



## Noob1234_1234 (14. Jan 2020)

Wo ist mein Denkfehler bei der Datenkapselung ? Wie greife ich in meiner Crane Klasse auf Attribute von ContainerStack zu ? Das ist nicht das erste Mal, dass ich diesen Fehler habe, aber ich checke net wo das Basisproblem liegt


```
public class Crane {

    private static final int maxHeight = 2438; // 160 Fuß entsprechen 2438,4 cm
    private static final int maxloadCapacity = 30; // in Tonnen
    private ContainerStack origin;
    private ContainerStack destination;

    public static int getMaxheight() {
        return maxHeight;
    }

    public static int getMaxloadcapacity() {
        return maxloadCapacity;
    }

    public void transportContainer(int number, int secondNumber) {
        if (origin.getContainerStackID() == number && destination.getContainerStackID() == secondNumber) {

            /*if (Crane.getMaxloadcapacity() >= origin.getContainerWeight()

                    && Crane.getMaxheight() >= (Crane.getMaxheight() - destination.calculateContainerStackHeight())) {*/

                Container c = origin.pick();
                destination.place(c);
            }
        }
    }
//}
```


----------



## mihe7 (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> in dem Fall war es ein Enum


Nein, nicht Container  Ich wollte wissen, was container denn sein soll:


Noob1234_1234 hat gesagt.:


> return String.format("%s;%s;%s;%s", container.getContainertyp(), container.getId(), container.getWeight(), containerStackID);


container dürfte null sein -> NullPointerException.


----------



## Noob1234_1234 (14. Jan 2020)

mihe7 hat gesagt.:


> Nein, nicht Container  Ich wollte wissen, was container denn sein soll:
> 
> container dürfte null sein -> NullPointerException.



Hab jetzt die ganzen Attribute und Methoden static deklariert und jetzt wird zumindest das richtige ausgegeben ohne Fehler. Aber ich krieg die eine Kran Methode nicht hin. Kann mir bitte wer zeigen, wie ich der Methode 2 Ganzzahlen geben kann, sodass sie dann automatisch ermitteln kann, um welche Stapel es sich handelt? Ich sitze echt schon den ganzen Tag hier dran und hab kb mehr. Aber ich bin glaub ich kurz davor. Nur diese Methode macht mich kaputt


----------



## Noob1234_1234 (14. Jan 2020)

Dafür brauch ich doch bestimmt eine Hilfsmethode, aber wie  ???


----------



## mrBrown (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Hab jetzt die ganzen Attribute und Methoden static deklariert und jetzt wird zumindest das richtige ausgegeben ohne Fehler.


Das solltest du direkt wieder rückgängig machen, das ist genau der falsche Weg 


Noob1234_1234 hat gesagt.:


> Also erstens soll der Kran zwei Zahlen (Integer entgegennehmen) und anhand von diesen die jeweiligen Stapel finden.


wo kommt denn zB diese Info her? In der Aufgabenstellung oben steht dazu nichts


----------



## Noob1234_1234 (14. Jan 2020)

mrBrown hat gesagt.:


> Das solltest du direkt wieder rückgängig machen, das ist genau der falsche Weg
> 
> Was ist denn dann der richtige Weg? Ich hab mich den ganzen Tag damit beschäftigt und mich überall eingelesen. Ich find nichts. Bitte sag mir, wenn du was weißt
> 
> wo kommt denn zB diese Info her? In der Aufgabenstellung oben steht dazu nichts


Aufgabe :  Ich muss eine Textdatei einlesen und in der steht das
<Ursprung >;< Ziel >
Das Token <Ursprung > steht für die Ursprungsstapel-Nummer und ist wieder eine positive int-Zahl inklusive 0. Das Token <Ziel > steht für die Zielstapel-Nummer und ist wieder eine positive int-Zahl inklusive 0. Aber wie greift mein Kran auf die Stapelnummer von meinen Stapeln zu ?


----------



## mrBrown (14. Jan 2020)

Nur weil in einer Textdatei zwei Zahlen stehen, heißt das nicht, dass dein Modell eine Methode besitzen muss, die genau diese beiden Zahlen bekommt.




Noob1234_1234 hat gesagt.:


> Der Containertransport geschieht in vier Schritten:
> 1. Positioniere Kran vor Ursprungsstapel
> 2. Entnehme obersten Container („pick“)
> 3. Positioniere Kran vor Zielstapel
> 4. Lege zuvor aufgenommenen Container zuoberst ab („place“)


Dieses (Falls Teil der Aufgabenstellung) würde ich zumindest anders interpretieren.



Spoiler



Ich würde 1-4 genau so in Terminal erwarten, in Pseudocode etwa:

```
kran.positioniereVor(ursprungsstapel)
kran.pick()
kran.positioniereVor(zielstapel)
kran.place()
```


----------



## Noob1234_1234 (14. Jan 2020)

mrBrown hat gesagt.:


> Nur weil in einer Textdatei zwei Zahlen stehen, heißt das nicht, dass dein Modell eine Methode besitzen muss, die genau diese beiden Zahlen bekommt.
> 
> 
> 
> ...



Ich hab aber trotzdem noch das Problem mit dem Zugriff auf andere Klassen. Ich weiß ich stell mich in euren Aufgaben sehr dumm an, aber wie greift dann meine ContainerStack Klasse auf die Inhalte, gespeicherten Werte etc der Container zu ? 
Wie greift mein Kran auf die ContainerStackKlasse zu und kann zum bso die getContainerNumber in der Kran klasse aufrufen? 
Genau das ist doch mein grundlegendes Problem. Ich steh absolut auf dem Schlauch und nichts will mehr klappen, aber danke dir schon mal. Dann muss ich den Transport Vorgang doch nicht in einem machen, aber kann mir bittr wer mein grundlegendes Problem lösen?


----------



## Noob1234_1234 (14. Jan 2020)

mrBrown hat gesagt.:


> Nur weil in einer Textdatei zwei Zahlen stehen, heißt das nicht, dass dein Modell eine Methode besitzen muss, die genau diese beiden Zahlen bekommt.



Aber die Zahlen die später in der Textdatei stehen, werden übergeben. Die 1. Positioniert den kran auf den stapel, dann wird das oberste gepickt und dsnn wird der Kran auf die 2. Zahl(anderer stapel) gesetzt . Weiß nicht ob das deine Absicht war, aber du hast mich auf eine Idee gebracht. Kann es sein, dass ich dem Kran ein Attribut "Position" mit settern/gettern geben muss und dem Konstruktor diese Position mitgeben muss?


----------



## mrBrown (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Aber die Zahlen die später in der Textdatei stehen, werden übergeben. Die 1. Positioniert den kran auf den stapel, dann wird das oberste gepickt und dsnn wird der Kran auf die 2. Zahl(anderer stapel) gesetzt .


Und? Nur weil die irgendwo benutzt werden müssen, muss der Kran die trotzdem nicht kennen 



Noob1234_1234 hat gesagt.:


> Weiß nicht ob das deine Absicht war, aber du hast mich auf eine Idee gebracht.


Dich auf eine Idee zu bringen war Absicht 



Noob1234_1234 hat gesagt.:


> Kann es sein, dass ich dem Kran ein Attribut "Position" mit settern/gettern geben muss und dem Konstruktor diese Position mitgeben muss?


Würde ich zumindest machen, wobei man da am Konstruktor nichts machen muss (außer du möchtest modellieren, dass ein neuer Kran für jeden Stapel gebeut werden soll)


----------



## mihe7 (14. Jan 2020)

Noob1234_1234 hat gesagt.:


> Weiß nicht ob das deine Absicht war, aber du hast mich auf eine Idee gebracht.


ROFL. Wie kommst Du denn nur darauf? In Wahrheit schreiben wir die Kommentar hier nur, um die Leute zu ärgern und dann passiert ausgerechnet @mrBrown so etwas


----------



## Noob1234_1234 (14. Jan 2020)

mrBrown hat gesagt.:


> Und? Nur weil die irgendwo benutzt werden müssen, muss der Kran die trotzdem nicht kennen


Wieso nicht ? Das ist der Part den Ich nicht kapiere ? Der Kran muss doch überprüfen, ob die Zahl die er bekommt zu einem Stapel gehört? Bzw er muss doch auf den Inhalt von der Containerklasse zugreifen ? Weil ich will im Kran in der methode irgendwo durch den Stack iterrieren um die mitgegebene int nummer mit stack.getContainerStackNumber zu vergleichen ? Wenn sie da ist muss die Position des Krans doch auf die bestätigte zahl setzen oder nicht? Oder passiert das alles erst in der TerminalContainer klasse? Aber dann ist mir imemrnoch nicht klar, wie die Methoden für den Kran aussehen ? Passieren die ganzen Überprüfungen im Kran selbst oder im Terminal?????



mrBrown hat gesagt.:


> Dich auf eine Idee zu bringen war Absicht
> 
> 
> Würde ich zumindest machen, wobei man da am Konstruktor nichts machen muss (außer du möchtest modellieren, dass ein neuer Kran für jeden Stapel gebeut werden soll)



Ne ne die Aufgabe gibt vor, dass es nur einen Kran für das Terminal gibt. Dem Konstruktor hätte ich eh nur die position mitgegeben, damit man den Kran im Terminal ein mal beliebig positioniert und halt dann den einen Kran auf die Positionen stellt.


----------



## mrBrown (14. Jan 2020)

Bitte achte doch beim Zitieren darauf, deinen eigenen Text nicht mit in das Zitat zu schreiben.



Noob1234_1234 hat gesagt.:


> Wieso nicht ? Das ist der Part den Ich nicht kapiere ? Der Kran muss doch überprüfen, ob die Zahl die er bekommt zu einem Stapel gehört? Bzw er muss doch auf den Inhalt von der Containerklasse zugreifen ? Weil ich will im Kran in der methode irgendwo durch den Stack iterrieren um die mitgegebene int nummer mit stack.getContainerStackNumber zu vergleichen ? Wenn sie da ist muss die Position des Krans doch auf die bestätigte zahl setzen oder nicht? Oder passiert das alles erst in der TerminalContainer klasse?


Das alles muss nicht im Kran passieren - das Terminal hat Kran und Stapel, also kann das Terminal sich auch darum kümmern.



Noob1234_1234 hat gesagt.:


> Aber dann ist mir imemrnoch nicht klar, wie die Methoden für den Kran aussehen ?


In meinem Vorschlag: `public void positioniereVor(ContainerStack ...)`, `public void pick()` und `public void place()`. Füllen musst du die natürlich selbst.



Noob1234_1234 hat gesagt.:


> Passieren die ganzen Überprüfungen im Kran selbst oder im Terminal?????


Kommt drauf an, was du mit "die ganzen Überprüfungen" meinst.

Die Überprüfung, wo der Kran hingestellt werden muss: Terminal.
Die Überprüfung, ob der Kran den Container von einem Stapel heben kann: Kran.



Noob1234_1234 hat gesagt.:


> Ne ne die Aufgabe gibt vor, dass es nur einen Kran für das Terminal gibt. Dem Konstruktor hätte ich eh nur die position mitgegeben, damit man den Kran im Terminal ein mal beliebig positioniert und halt dann den einen Kran auf die Positionen stellt.


Das ist natürlich auch möglich


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Wieso nicht ? Das ist der Part den Ich nicht kapiere ?


Genau deswegen bekommst Du Aufgaben gestellt, bei denen es um Modellierung geht. Das ist auch der Grund, warum ich hier auf dem Modell rumreite und relativ wenig zum Code geschrieben habe. Es bringt nichts, wenn Du Dich mit Code herumquälst, so lange das Modell nicht in Ordnung ist.



Noob1234_1234 hat gesagt.:


> Der Kran muss doch überprüfen, ob die Zahl die er bekommt zu einem Stapel gehört? Bzw er muss doch auf den Inhalt von der Containerklasse zugreifen ? Weil ich will im Kran in der methode irgendwo durch den Stack iterrieren um die mitgegebene int nummer mit stack.getContainerStackNumber zu vergleichen ?



Die Aufgabe des Krans ist es, Container zu bewegen. Dazu kann er zu einem Containerstapel gefahren werden. Die Aufgabe des Krans ist nicht zu wissen, wo sich der Stapel mit der Nummer 4711 im Terminal befindet.

Dieses Wissen hat das Terminal. Aus Sicht der Modellierung stellt sich nur noch die Frage, ob es vernünftiger ist, wenn das Terminal den Kran kennt oder umgekehrt. 

Man darf nicht vergessen, dass ein Modell, ganz allgemein, eine vereinfachende Abbildung eines Originals ist, die einem bestimmten Zweck dient. Ein Modell kann die Wirklichkeit nicht wahrheitsgemäß abbilden, ein Modell muss nur dazu taugen, den entsprechenden Zweck zu erfüllen. 



Spoiler: Landkarten als Modelle



Wenn Du z. B. in Google Maps o. ä. Dir die Karte der Welt ansiehst, stellst Du fest, dass Grönland dort fast so groß wie Afrika erscheint, obwohl Afrika etwa die 15-fache Fläche besitzt. Die Karte ist so gesehen falsch. Das macht aber nichts, da die Karte "nur" ein Modell ist, das einem Zweck dienen muss. Die Abbildung der Erde erfolgt bei diesen Karten nicht flächen- sondern winkeltreu, weil es in der Navigation (= Zweck) um korrekte Kurse (Winkel) und nicht um korrekte Flächen geht.



Man könnte sich überlegen, ein vollautomatisches Container Terminal zu bauen. Dem Terminal erteilt man nur einen Auftrag und das Terminal führt diesen selbsttätig aus. So spielt es für den Anwender des Terminals beispielsweise keine Rolle, ob dieses über einen einzigen Kran oder über 25 Kräne verfügt und welcher Kran welchen Beförderungsauftrag regelt. Ebenso uninteressant ist es für den Anwender zu wissen, wo die Container(stapel) genau stehen usw. Der Anwender sagt nur: "liebes Terminal, bitte sorge dafür, dass der oberste Container vom Stapel 0815 auf den Stapel 4711 geschoben wird".

In dem Fall muss das Terminal wissen (oder in Erfahrung bringen können), welche Stapel mit 0815 und 4711 gemeint sind und kann den Kran entsprechend instruieren. 

Der Kran wiederum muss sicherstellen, dass er keinen Unsinn treibt. Der Kran weiß, ob er den Container hochheben kann und ob er ihn "ausreichend hoch" heben kann, um ihn auf dem Zielstapel platzieren zu können. 

Der Stapel dagegen weiß, aus welchen Containern er besteht und kennt daher auch die aktuelle Gesamthöhe.

Derlei Überlegungen führen dann zu einem Modell, dessen Zweckmäßigkeit Du gedanklich überprüfen kannst, indem Du die Aufgabe anhand des Modells durchspielst. 

Wenn Du soweit bist, dann kannst Du anfangen, den Spaß in Code zu gießen.


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Genau deswegen bekommst Du Aufgaben gestellt, bei denen es um Modellierung geht. Das ist auch der Grund, warum ich hier auf dem Modell rumreite und relativ wenig zum Code geschrieben habe. Es bringt nichts, wenn Du Dich mit Code herumquälst, so lange das Modell nicht in Ordnung ist.
> 
> 
> 
> ...


Ich glaube wir reden alle aneinander vorbei. Ihr habt mir echt viel bei der Modellierung geholfen und inzwischen ist mir auch klar, was der Sinn vom Terminal ist, aber mein grundlegendes Problem/Frage, die ich schon 3 oder 4 mal gestellt habe, wird mir nicht beantwortet. 
Wie lass ich denn den Kran auf die Container zugreifen? Ich hab alles auf static gesetzt und so klappts, aber mir wurde schon gesagt, dass das der falsche Weg ist und mir ist das ja auch bewusst, aber ich versteh es echt nicht? 


```
public class Crane {

    private static final int maxHeight = 2438; // 160 Fuß entsprechen 2438,4 cm
    private static final int maxloadCapacity = 30000;
    private int position;

    public static int getMaxheight() {
        return maxHeight;
    }

    public static int getMaxloadcapacity() {
        return maxloadCapacity;
    }

    public Crane(int position) {
        setPosition(position);
    }

    public void setPosition(int position) {
        this.position = position;
    }

    public void cranePositioningOrigin(int stackNumber) {
        setPosition(stackNumber);
    }

    public void cranePositioningDestination(int stackNumber2) {
        setPosition(stackNumber2);
    }

    public Container pick() { // Brauche ich pick und place überhaupt ??? oder kann ich meine positioning methoden mit der transport methode kopieren?
        
    }

    public Container place() {

    }

    public void transportContainer(ContainerStack origin, ContainerStack destination) {
    
    // Legitim ?
        if (Crane.getMaxloadcapacity() >= origin.getContainerWeight()
                && Crane.getMaxheight() >= (Crane.getMaxheight() - destination.calculateContainerStackHeight())) {

            Container c = origin.pick();
            destination.place(c);
        } else {
            System.out.println("zu schwer oder zu hoch");
        }
    }
}
```


----------



## Noob1234_1234 (15. Jan 2020)

Laut euren Beschreibungen dachte ich, dass die Überprüfung ob und was der Kran kann auch vom Terminal passiert, denn ihr habt ja beide schon festgestellt, dass nur das Terminal sowohl Zugriff auf den Kran hat als auch auf den Stapel und da nur der Stapel Auskunft über die Container hat, kann doch auch nur das Terminal entscheiden, ob der Kran was kann oder nicht ? 

Ich hab in der Aufgabe noch eine Testein- und ausgabe. Diese wird als Textdatei gelesen und soll entsprechend das gleiche wie aufm Blatt raus kommen


----------



## mrBrown (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Ich glaube wir reden alle aneinander vorbei. Ihr habt mir echt viel bei der Modellierung geholfen und inzwischen ist mir auch klar, was der Sinn vom Terminal ist, aber mein grundlegendes Problem/Frage, die ich schon 3 oder 4 mal gestellt habe, wird mir nicht beantwortet.
> Wie lass ich denn den Kran auf die Container zugreifen? Ich hab alles auf static gesetzt und so klappts, aber mir wurde schon gesagt, dass das der falsche Weg ist und mir ist das ja auch bewusst, aber ich versteh es echt nicht?


Dein Problem lässt sich nicht von der Modellierung trennen 

In Kran brauchst du die Position nicht als int, oder steht der Kran vor einer Zahl?
Bring einfach mal den Satz zu Ende: „Der Kran steht vor einem ___“




Noob1234_1234 hat gesagt.:


> Laut euren Beschreibungen dachte ich, dass die Überprüfung ob und was der Kran kann auch vom Terminal passiert, denn ihr habt ja beide schon festgestellt, dass nur das Terminal sowohl Zugriff auf den Kran hat als auch auf den Stapel und da nur der Stapel Auskunft über die Container hat, kann doch auch nur das Terminal entscheiden, ob der Kran was kann oder nicht ?


Das Terminal kennt zwar den Kran, aber nur der Kran kennt seine eigenen Daten.
Nur das Terminal kennt alle ContainerStapel - aber deshalb soll der Kran ja entsprechend positioniert werden, dann kann auch der Kran den jeweiligen Stapel kennen.


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> aber mein grundlegendes Problem/Frage, die ich schon 3 oder 4 mal gestellt habe, wird mir nicht beantwortet.
> Wie lass ich denn den Kran auf die Container zugreifen?


Die Hoffnung besteht darin, dass der Fragesteller selbst auf die Lösung kommt. Das Problem hat sich nämlich nie wirklich gestellt. Du hast es nur zu einem Problem gemacht, weil Du im Kran unbedingt eine Stapelnummer haben willst.


----------



## Noob1234_1234 (15. Jan 2020)

mrBrown hat gesagt.:


> Dein Problem lässt sich nicht von der Modellierung trennen
> 
> In Kran brauchst du die Position nicht als int, oder steht der Kran vor einer Zahl?
> Bring einfach mal den Satz zu Ende: „Der Kran steht vor einem ___“


Containerstapel?




mrBrown hat gesagt.:


> Das Terminal kennt zwar den Kran, aber nur der Kran kennt seine eigenen Daten.
> Nur das Terminal kennt alle ContainerStapel - aber deshalb soll der Kran ja entsprechend positioniert werden, dann kann auch der Kran den jeweiligen Stapel kennen.


----------



## Noob1234_1234 (15. Jan 2020)

Ihr beiden seht wohl die Lösung schon, aber ich hänge auf dem Schlauch.... 


mihe7 hat gesagt.:


> Die Hoffnung besteht darin, dass der Fragesteller selbst auf die Lösung kommt. Das Problem hat sich nämlich nie wirklich gestellt. Du hast es nur zu einem Problem gemacht, weil Du im Kran unbedingt eine Stapelnummer haben willst.


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Ihr beiden seht wohl die Lösung schon, aber ich hänge auf dem Schlauch....


Die Lösung gab es schon die ganze Zeit: `void transportContainer(ContainerStack origin, ContainerStack destination)`, nur dass Du mir hier


mihe7 hat gesagt.:


> Nachtrag: wie ich gerade lese, wird es die Methode so nicht geben, da die Transportschritte einzeln durchzuführen sind.


nicht glauben wolltest. Jetzt wird die Methode halt in einzelne Schritte aufgeteilt. Und der Kran vor einem


Noob1234_1234 hat gesagt.:


> Containerstapel


positioniert.


----------



## Noob1234_1234 (15. Jan 2020)

Hä dann ist es doch so oder wie ? Aber wo geb ich die Zahlen bitte mit und wie kombiniere ich das. Sobald alles klappt muss ich noch eine main Methode schreiben, die eine Textdatei lesen und anwenden kann. In der Textdatei steht dann irgendwo 2 Zeilen (1. Zeile 2,0 und 2. Zeile 3,2) und das bedeutet dann, dass der oberste Container vom Stappel 2 auf den 0. gepackt wird, und der oberste Container von 3 auf den 2. Stappel. Und hier liegt ja das Problem, wo nimmt mein Programm die 2 Werte entgegen und wie verarbeitet er sie ?

```
public void transportContainer(ContainerStack origin, ContainerStack destination) {

        if (Crane.getMaxloadcapacity() >= origin.getContainerWeight()
                && Crane.getMaxheight() >= (Crane.getMaxheight() - destination.calculateContainerStackHeight())) {

            Container c = origin.pick();
            destination.place(c);
        } else {
            System.out.println("zu schwer oder zu hoch");
        }
    }
```


----------



## mrBrown (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Hä dann ist es doch so oder wie ?


Nein, wie @mihe7 sagte, muss die Methode in einzelne Schritte aufgeteilt werden.

Kümmer dich erstmal *nur* um das Positionieren. Wenn das fertig ist, kann man sich um den Rest kümmern.




Noob1234_1234 hat gesagt.:


> Und hier liegt ja das Problem, wo nimmt mein Programm die 2 Werte entgegen und wie verarbeitet er sie ?


Später mal in main und Terminal, aber das ist grad noch irrelevant.


----------



## Noob1234_1234 (15. Jan 2020)

Ich schätze mal mein Ansatz ist falsch, wenn du schon sagst kümmer dich ums Positionieren oder ?


```
public void setPosition(int position) {
        this.position = position;
    }

    public void cranePositioningOrigin(int stackNumber) {
        setPosition(stackNumber);
    }

    public void cranePositioningDestination(int stackNumber2) {
        setPosition(stackNumber2);
    }

    public Container pick(ContainerStack origin) {
        return origin.pick();
    }

    public void place(Container container, ContainerStack destination) {
        destination.place(container);
    }
```


----------



## Javinner (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Positioniere Kran vor Ursprungsstapel
> Entnehme obersten Container („pick“)
> Positioniere Kran vor Zielstapel
> Lege zuvor aufgenommenen Container zuoberst ab („place“)


Dein Ursprungstapel hat:

Container 1
Container 2
Container...
1 & 2:
Nimm ein Container aus dem Ursprungsstapel wenn das Gewicht vom Kran getragen werden kann.

```
class Stapel

{

    private Container aktuellerContainer;

   

    public Container gebeAktuellenContainer()

    {

        return this.aktuellerContainer;

    }

}

class Kran
{
    private final double maxHeben;
   
    //...
   
   
    boolean kannContainerHeben(Container container)
    {
        return this.maxHeben >= container.gebeGewicht();
    }
}
```
Wenn nicht der Fall, tausche ersten Container gegen nächst liegenden aus, wiederhole die Prüfung.


3 & 4
Lege den Container, den Kran gerade transportiert, auf der ersten Stelle ab. Eine LinkedList bietet hier eine Methode mit dem Namen addFirst(E e) an. Man könnte jetzt die vorhandenen Strukturen nehmen oder aber auch eine eigene Lösung entwickeln.


----------



## mrBrown (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Ich schätze mal mein Ansatz ist falsch, wenn du schon sagst kümmer dich ums Positionieren oder ?


Du brauchst *keinen* int für die Position innerhalb des Krans.

Du brauchst etwa diese Methoden, mit genau den Signaturen: 



mrBrown hat gesagt.:


> In meinem Vorschlag: `public void positioniereVor(ContainerStack ...)`, `public void pick()` und `public void place()`. Füllen musst du die natürlich selbst.


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Ich schätze mal mein Ansatz ist falsch,


Ja. Dein Kran muss lediglich 


Noob1234_1234 hat gesagt.:


> 1. Positioniere Kran vor Ursprungsstapel
> 2. Entnehme obersten Container („pick“)
> 3. Positioniere Kran vor Zielstapel
> 4. Lege zuvor aufgenommenen Container zuoberst ab („place“)


unterstützen.

D. h.



Dabei bewegt die Methode moveTo() den Kran zum angegebenen Stapel, pick() nimmt von dem Stapel, vor dem der Kran aktuell steht, den obersten Container und mit place() wird der Container, der gerade am Kran hängt, auf dem Stapel abgelegt, vor dem der Kran aktuell steht.


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Ja. Dein Kran muss lediglich
> 
> unterstützen.
> 
> ...



Och man ich hab das alles doch schon die ganze vor mir. Ich hab alle Antworten 10000 durchgelesen, aber ich checke es nicht. Wie sieht die moveTo Methode bitte aus. Mir ist doch klar, dass sie zum jewiligen Stapel soll, aber ich hab keine Ahnung wie ich das umsetzen soll. Was kommt in die Klammer der Methode, wenn s kein int ist??? Leute bitte ich bin echt am verzweifeln und ich hänge an diesem Punkt seit gestern und es fehlt noch einiges.


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Ja. Dein Kran muss lediglich
> 
> unterstützen.
> 
> ...



Hat dieses " s : Containerstack" eine spezielle Bedeutung ? Seh ich jetzt so zum ersten Mal, Kenn den Doppelpunkt nur von der for each Schleife


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Seh ich jetzt so zum ersten Mal


Womit modelliert ihr denn? Das ist die normale UML-Schreibweise. Übersetzt in Java wäre das einfach `ContainerStack s`.


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Womit modelliert ihr denn? Das ist die normale UML-Schreibweise. Übersetzt in Java wäre das einfach `ContainerStack s`.


Ich kenn UML nicht. Uns wurde modellieren nicht so beigebracht. 

Das kann so auch noch nicht stimmen, aber gehts jetzt in die richtige Richtung ?

```
public void moveTo(ContainerStack s) {
        s.getContainerStackID();
    }
```


----------



## Noob1234_1234 (15. Jan 2020)

Oder so? Es muss ja einen Rückgabewert haben, sonst mach das ganze doch kein Sinn oder ?

```
public int moveTo(ContainerStack s) {
        return s.getContainerStackID();
    }
```


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Uns wurde modellieren nicht so beigebracht.


Womit modelliert ihr dann?



Noob1234_1234 hat gesagt.:


> Es muss ja einen Rückgabewert haben, sonst mach das ganze doch kein Sinn oder ?


Wozu? Die Methode muss lediglich dafür sorgen, dass der Kran zum angegebenen Stapel fährt, also seine Position ändert.


```
public class Crane {
    private ContainerStack position; // aktuelle Position des Krans

    public void moveTo(ContainerStack stack) { // fährt den Kran zu stack,
        position = stack; // womit sich die aktuelle Position ändert
    }
}
```


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Womit modelliert ihr dann?
> 
> 
> Wozu? Die Methode muss lediglich dafür sorgen, dass der Kran zum angegebenen Stapel fährt, also seine Position ändert.
> ...



Ich check aber immernoch nicht, wo hier dann die Integer ins Spiel kommen? Passiert das später oder wie habt ihr euch das vorgestellt ? 

Passt das jetzt? 


```
public void moveTo(ContainerStack stack) {
        position = stack;
    }

    public Container pick(ContainerStack origin) {
        return origin.pick();
    }

    public void place(Container container, ContainerStack destination) {
        destination.place(container);
    }
```


----------



## mrBrown (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Ich check aber immernoch nicht, wo hier dann die Integer ins Spiel kommen? Passiert das später oder wie habt ihr euch das vorgestellt ?


In Kran brauchst du keinen Integer, der kommt später in Terminal ins Spiel.



Noob1234_1234 hat gesagt.:


> Passt das jetzt?


pick und place brauchen beide *keine* Argumente.


----------



## Noob1234_1234 (15. Jan 2020)

mrBrown hat gesagt.:


> In Kran brauchst du keinen Integer, der kommt später in Terminal ins Spiel.


Okey da vertrau ich euch mal. 

pick und place brauchen beide *keine* Argumente.
[/QUOTE]
Dass pick keins braucht, das versteh ich noch, aber braucht place nicht Container als Argument?


```
public void moveTo(ContainerStack stack) {
        position = stack;
    }

    public Container pick() {
        return position.pick();
    }

    public void place(Container container) {
        position.place(container);
    }
```


----------



## mrBrown (15. Jan 2020)

Sie brauchen auch alle keine Rückgabe.



Noob1234_1234 hat gesagt.:


> Dass pick keins braucht, das versteh ich noch, aber braucht place nicht Container als Argument?



Der Kran soll den Container hochheben und transportieren - sollte der Kran dann vielleicht den Container, den er grad transportiert, kennen, und muss den nicht übergeben bekommen?


----------



## Noob1234_1234 (15. Jan 2020)

mrBrown hat gesagt.:


> Sie brauchen auch alle keine Rückgabe.
> 
> 
> 
> Der Kran soll den Container hochheben und transportieren - sollte der Kran dann vielleicht den Container, den er grad transportiert, kennen, und muss den nicht übergeben bekommen?



Aber der Kran muss den Container doch zuoberst auf den Zielstack ablegen ? Wenn der Kran also beim Zielstapel ist, muss er ja was placen, außer natürlich er plact etwas neues ?
So?

```
public void place() {
        position.place(new Container());
    }
```


```
Edit: So müsste es aussehen

public void place() {
        position.place(position.pick());
    }
```


----------



## Noob1234_1234 (15. Jan 2020)

Mein Kran sollte ja jetzt die Fähigkeit haben die Container zu bewegen. Fällt damit die 4. Methode vom Anfang weg und wird in den Logistikbereich des Terminals verschoben oder bliebt sie beim Kran ?


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> So?


Nein, Du musst in einer Variablen speichern, was am Kran hängt.


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Nein, Du musst in einer Variablen speichern, was am Kran hängt.



Was denn jetzt xD? MrBrown meinte alle 3 Methoden haben keine Rückgabetyp und es könnte sein, dass er recht hat, weil so müsste doch der Aufbau des Transports sein:


```
public void transportContainer(ContainerStack origin, ContainerStack destination) {
        moveTo(origin);
        if (Crane.getMaxloadcapacity() >= origin.getContainerWeight()
                && Crane.getMaxheight() >= (Crane.getMaxheight() - destination.calculateContainerStackHeight())) {
            pick();
            moveTo(destination);
            place();
        } else {
            System.out.println("zu schwer oder zu hoch");
        }
```


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Nein, Du musst in einer Variablen speichern, was am Kran hängt.



die pick methode der StackContainer speichert doch die Variable also sollte alles passen oder ?


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Was denn jetzt xD? MrBrown meinte alle 3 Methoden haben keine Rückgabetyp und es könnte sein, dass er recht hat


Ja, das schließt einander ja nicht aus, im Gegenteil.

Deine Methode

```
public void place() {
        position.place(position.pick());
    }
```
macht nichts anderes, als von dem Stapel, vor dem der Kran gerade steht, den obersten Container herunterzunehmen (position.pick()), um ihn gleich wieder auf den selben Stapel abzulegen. Das ist doch Blödsinn.

Der Kran muss sich beim pick() merken, welchen Container er geladen hat, um diesen Container später beim place zu verwenden.

Ohne die notwendigen Prüfungen sähe der Code also in etwa so aus:


```
public class Crane {
    private Container load;

    // ...

    public void pick() {
        load = position.pick();
    }

    public void place() {
        position.place(load);
    }
}
```


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Ja, das schließt einander ja nicht aus, im Gegenteil.
> 
> Deine Methode
> 
> ...



Hab es jetzt so gemacht, wie du das gesagt hast, wobei ich glaube, dass meine Variante auch funktioniert, denn wenn ich den Move Befehl verwende speichert ja mein Kran zuerst die Ursprungsstaple position, nehmt den Container und bewegt sich doch dann zum Zielstapel und somit speichert er dann diese Position und legt es nicht zurück zum Anfang oder etwa doch? 

Aber deine Variante erscheint mir sicherer und einfacher zu verstehen


----------



## Noob1234_1234 (15. Jan 2020)

Ich hoffe jetzt passte es mit der Kran Klasse ? Weil dann fehlt nur noch die Umsetzung der Terminal Klasse. Bin echt gespannt, wie diese zwei Integer Werte ins Systems passen, weil ich seh es noch nicht


```
public class Crane {

    private static final int MAXHEIGHT = 2438; // 160 Fuß entsprechen 2438,4 cm
    private static final int MAXLOADCAPACITY = 30000;
    private ContainerStack position; // aktuelle Position des Krans
    private Container containerLoad;

    public static int getMaxheight() {
        return MAXHEIGHT;
    }

    public static int getMaxloadcapacity() {
        return MAXLOADCAPACITY;
    }

    public void moveTo(ContainerStack stack) {
        position = stack;
    }

    public void pick() {
        containerLoad = position.pick();
    }

    public void place() {
        position.place(containerLoad);
    }

    public void transportContainer(ContainerStack origin, ContainerStack destination) {
        moveTo(origin);
        if (Crane.getMaxloadcapacity() >= origin.getContainerWeight()
                && Crane.getMaxheight() >= (Crane.getMaxheight() - destination.calculateContainerStackHeight())) {
            pick();
            moveTo(destination);
            place();
        } else {
            System.out.println("zu schwer oder zu hoch");
        }
    }
}
```


----------



## mrBrown (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Hab es jetzt so gemacht, wie du das gesagt hast, wobei ich glaube, dass meine Variante auch funktioniert, denn wenn ich den Move Befehl verwende speichert ja mein Kran zuerst die Ursprungsstaple position, nehmt den Container und bewegt sich doch dann zum Zielstapel und somit speichert er dann diese Position und legt es nicht zurück zum Anfang oder etwa doch?


Nein, Place nimmt bei dir wie gesagt den Container vom aktuellen Stapel, und legt ihn dann direkt wieder auf den aktuellen Stapel.




Noob1234_1234 hat gesagt.:


> Ich hoffe jetzt passte es mit der Kran Klasse ?


transportContainer ist überflüssig.


----------



## mihe7 (15. Jan 2020)

Mal nebenbei gefragt: hat es eigentlich einen bestimmten Grund, dass Du die Höhen in das metrische System umrechnest?


----------



## Noob1234_1234 (15. Jan 2020)

mrBrown hat gesagt.:


> Nein, Place nimmt bei dir wie gesagt den Container vom aktuellen Stapel, und legt ihn dann direkt wieder auf den aktuellen Stapel.
> 
> 
> 
> transportContainer ist überflüssig.


Also brauch ich diese Methode später nicht in der Terminal Klasse? Dachte die KranKlasse muss die Überprüfungen machen, ob sie kann, was das Terminal will? 

Aber wie soll denn jetzt die Terminalklasse aufgebaut sein? Es gibt einen Kran und beliebig viele Stapel ?


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Mal nebenbei gefragt: hat es eigentlich einen bestimmten Grund, dass Du die Höhen in das metrische System umrechnest?



Fällt mir leichter so oder denkst du es wäre besser wenn ich bei Fuß und Zoll bleibe ? Dann müsste ich ja double/float verwenden, was aber in dem Sinne keinen Unterschied macht


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Dachte die KranKlasse muss die Überprüfungen machen, ob sie kann, was das Terminal will?


Ja, muss sie auch. Die Prüfungen gehören insbesondere in die Methoden pick() und place().



Noob1234_1234 hat gesagt.:


> Fällt mir leichter so oder denkst du es wäre besser wenn ich bei Fuß und Zoll bleibe ? Dann müsste ich ja double/float verwenden, was aber in dem Sinne keinen Unterschied macht


Durch die Umrechnung hast Du Rundungsfehler, die sich addieren. Wenn Du z. B. die Höhe 9'6'', also 114'' in Zentimeter umrechnest, kommst Du auf 289 Zentimeter bei Abrundung bzw. 290 Zentimeter bei Aufrundung. Das macht bei Abrundung einen Fehler von 0,56 Zentimeter pro Container, so dass die Gesamthöhe von 5 übereinander gestapelten Containern um über einen Zoll von der tatsächlichen Höhe abweicht (5 x 0,56 cm = 2,8 cm, also etwas mehr als 1.1'')

Bleibst Du dagegen bei Zoll, brauchst Du auch keine Dezimalzahlen, hast aber das exakte Ergebnis: ein Container ist 114 Zoll hoch. 5 Container übereinander machen 570 Zoll. Der Kran ist 160 Fuß, also 1920 Zoll hoch -> alles kein Problem.


----------



## mrBrown (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Also brauch ich diese Methode später nicht in der Terminal Klasse?


In ähnlicher Form, aber in Kran brauchst du sie in jedem Fall nicht.




Noob1234_1234 hat gesagt.:


> Dachte die KranKlasse muss die Überprüfungen machen, ob sie kann, was das Terminal will?


Richtig - das fehlt noch.
Dafür brauchst du aber keine zusätzliche Methode, du musst nur die bestehenden Methoden des Krans ergänzen.
Wo könnte man die Dinge denn sinnvoll prüfen?


Noob1234_1234 hat gesagt.:


> Fällt mir leichter so oder denkst du es wäre besser wenn ich bei Fuß und Zoll bleibe ? Dann müsste ich ja double/float verwenden, was aber in dem Sinne keinen Unterschied macht


2438,4 ist einfacher als 160?


----------



## Noob1234_1234 (15. Jan 2020)

So wäre mein Ansatz : 
Alle paramter, die in  der Methode stehen müssen mitgegeben werden 


```
public class ContainerTerminal {

    final Crane crane = new Crane();

    public void terminalDoWorkContainer(String containertyp, int id, int weight, int stacknumber, int origin,
            int destination) {

        ContainerStack cs0 = new ContainerStack(stacknumber);
        cs0.place(new Container40ft(containertyp, id, weight));
// hier drinnne dann der Transport?
        Terminal.printLine(cs0);

    }
```


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> So wäre mein Ansatz :


Mach doch erstmal den Kran fertig. Da fehlt ja noch die Hälfte (=Prüfungen).



Noob1234_1234 hat gesagt.:


> So wäre mein Ansatz :


Grober Unfug. 

Schau Dir nochmal das Diagramm an (aktualisierte Version und ohne die Container-Implementierungen), in dem natürlich immer noch Dinge fehlen:


----------



## Noob1234_1234 (15. Jan 2020)

Mit meinem Ansatz jedoch wird jedes mal ein neuer Stack erstellt, also selbst wenn man 2x eine 1 einsetzt für die stacknumber, dann entstehen quasi 2 Stapel, die 1 heißen und das ist ja nicht Sinn der Sache. Jeder neue Stack sollte eigentlich von 0 aufsteigend durchnummeriert sein (Ich hatte dafür eine Methode, aber auch hier wird die Nummer durch die Textdatei mitgegeben und das verwirrt mich). Irgendwer eine Idee für die Lösung dafür ? 

und wie stelle ich sicher, dass bei gleicher Eingabe von Stacknumer nicht ein neuer Stack erstellt wird, sondern, dass der entsprechende Container nur auf den Stappel kommt ? oder ist das für das Modell egal? ich hätte eine Map oder Set gedacht zur Umsetzung


----------



## Noob1234_1234 (15. Jan 2020)

Jetzt aber ?

```
public class Crane {

    private static final int MAXHEIGHT = 1920; // Zoll
    private static final int MAXLOADCAPACITY = 30000; // in kg
    private ContainerStack position; // aktuelle Position des Krans
    private Container containerLoad;

    public static int getMaxheight() {
        return MAXHEIGHT;
    }

    public static int getMaxloadcapacity() {
        return MAXLOADCAPACITY;
    }

    public void moveTo(ContainerStack stack) {
        position = stack;
    }

    public void pick() {
        if (MAXLOADCAPACITY >= containerLoad.getWeight()) {
            containerLoad = position.pick();
        }
    }

    public void place() {
        if (MAXHEIGHT >= (MAXHEIGHT - position.calculateContainerStackHeight())) {
            position.place(containerLoad);
        }
    }

}
```


----------



## mihe7 (15. Jan 2020)

Wir kommen der Sache näher aber Du machst es Dir zu einfach. Da fehlen noch einige Prüfungen. Überleg mal, was alles schief laufen könnte, wenn Du die einzelnen Methoden (in beliebiger Reihenfolge) aufrufst.


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Wir kommen der Sache näher aber Du machst es Dir zu einfach. Da fehlen noch einige Prüfungen. Überleg mal, was alles schief laufen könnte, wenn Du die einzelnen Methoden (in beliebiger Reihenfolge) aufrufst.



Eigentlich fehlt doch nur eine Überprüfung oder net ? In der Aufgabe steht, dass wenn der Stapel von vornherein zu groß ist, dann soll der Stapel gar nicht erst angehoben werden . Meinst du das ?

Edit : Und er kann immer nur ein Container tragen ?


----------



## Noob1234_1234 (15. Jan 2020)

Das sollte die eine Sache klären oder ? Aber wie leg ich fest, dass der Kran nur ein Container immer tragen kann 

```
public void pick() {
        if (testHeight() == true) {
            if (MAXLOADCAPACITY >= containerLoad.getWeight()) {
                containerLoad = position.pick();
            }
        }
    }
    
    //
    
    public boolean testHeight() {
        if (MAXHEIGHT >= (MAXHEIGHT - position.calculateContainerStackHeight())) {
            position.place(containerLoad);
            return true;
        }
        return false;
    }
```


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> In der Aufgabe steht, dass wenn der Stapel von vornherein zu groß ist, dann soll der Stapel gar nicht erst angehoben werden . Meinst du das ?


Nein, das meine ich nicht. Du sollst nicht in die Aufgabe schauen, sondern selbst das Denken anfangen. 

Du musst Dir den Spaß bildlich vorstellen. Nun kenne ich die Abbildung in der Aufgabe nicht, ich stelle mir daher einen Kran vor, der z. B. auf einer Schiene fahrbar ist und über einer Reihe von Containerstapeln steht. 



Noob1234_1234 hat gesagt.:


> Aber wie leg ich fest, dass der Kran nur ein Container immer tragen kann


Denken... Tipp: es hat mit der Ladung zu tun.


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Nein, das meine ich nicht. Du sollst nicht in die Aufgabe schauen, sondern selbst das Denken anfangen.
> 
> Du musst Dir den Spaß bildlich vorstellen. Nun kenne ich die Abbildung in der Aufgabe nicht, ich stelle mir daher einen Kran vor, der z. B. auf einer Schiene fahrbar ist und über einer Reihe von Containerstapeln steht.
> 
> ...




```
public void pick() {
        if (testHeight() == true) {
            if (MAXLOADCAPACITY >= containerLoad.getWeight()) {
                while (position.stack.size() < 1) {
                    containerLoad = position.pick();
                }
            }
        }
    }
```
Die Stackgröße darf nicht größer sein als 1 oder ? Also so wie hier


----------



## Meniskusschaden (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> ```
> if (MAXHEIGHT >= (MAXHEIGHT - position.calculateContainerStackHeight())) {
> ```


Wann kann diese Bedingung eigentlich falsch werden? Wenn nicht nur der Containerstapel, sondern auch der darunter liegende Keller leer geräumt wurde?


----------



## Noob1234_1234 (15. Jan 2020)

Meniskusschaden hat gesagt.:


> Wann kann diese Bedingung eigentlich falsch werden? Wenn nicht nur der Containerstapel, sondern auch der darunter liegende Keller leer geräumt wurde?


Oh Stimmt lol , aber das war der Teil den ich nicht mal inhaltlich verstanden habe, aber es muss andersherum sein oder nicht? Die MaxHöhe - höhe stapel muss größer gleich dem Stapel sein?


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Nein, das meine ich nicht. Du sollst nicht in die Aufgabe schauen, sondern selbst das Denken anfangen.
> 
> Du musst Dir den Spaß bildlich vorstellen. Nun kenne ich die Abbildung in der Aufgabe nicht, ich stelle mir daher einen Kran vor, der z. B. auf einer Schiene fahrbar ist und über einer Reihe von Containerstapeln steht.


Alles was nicht in der Aufgabe steht überleg ich mir erst, wenn ich die Aufgabe fertig habe xD, deswegen will ich erstmal das Terminal noch fertig machen (weil es da auch 3 Parts gibt, die mich endlos verwirren)

Denken... Tipp: es hat mit der Ladung zu tun.
[/QUOTE]


----------



## Meniskusschaden (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Die MaxHöhe - höhe stapel muss größer gleich dem Stapel sein?


Na ja, nehmen wir mal an, der Kran kann maximal 10m, der Stapel hat gerade 6m und der Container ist 2m hoch. Nach deiner Formel könnte der Kran das dann nicht machen, weil `10m - 6m >= 6m` false ergibt.


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Mach doch erstmal den Kran fertig. Da fehlt ja noch die Hälfte (=Prüfungen).
> 
> 
> Grober Unfug.
> ...


Welche Dinge fehlen denn im Container ?


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Welche Dinge fehlen denn im Container ?


Wieso im Container? Bzgl. des Containers habe ich nur die konkreten Klassen im Diagramm weggelassen.


----------



## Noob1234_1234 (15. Jan 2020)

Meniskusschaden hat gesagt.:


> Na ja, nehmen wir mal an, der Kran kann maximal 10m, der Stapel hat gerade 6m und der Container ist 2m hoch. Nach deiner Formel könnte der Kran das dann nicht machen, weil `10m - 6m >= 6m` false ergibt.



Okey du hast recht und ich bin jetzt noch mehr verwirrt -.- ; kannst du mir das bitte in eine mathematische Formel übersetzen. Ich checks imemrnoch :

"Ein Kran besitzt eine maximale Hubhöhe. Das ist die Höhe, die ein theoretisch vollkommen flacher Gegenstand der Höhe 0 angehoben werden könnte. Die tatsächliche Hubhöhe muss um die Höhe des angehobenen Gegenstands vermindert werden. Beträgt die maximale Hubhöhe 80 Fuß, so ergibt sich für einen 10 Fuß hohen Container eine tatsächlich erreichbare Hubhöhe von 70 Fuß. Falls die tatsächlich erreichbare Hubhöhe geringer als die Höhe des Zielstapels ist, ist es dem Kran nicht möglich, den Container auf dem Zielstapel zu platzieren. Der Container wird in diesem Fall gar nicht erst vom Ursprungsstapel entnommen. Stellen Sie die maximale Hubhöhe des Krans unveränderlich auf 160 Fuß ein. " 
Bin immernoch der Meinung, dass meine Formel stimmen muss, wobei du gerade ja gezeigt hast, dass es nicht sein kann


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Wieso im Container? Bzgl. des Containers habe ich nur die konkreten Klassen im Diagramm weggelassen.



Ahsooo ich dachte ich hab bei der Implementierung vergessen, aber eine Frage welche Klasse besitzt den Konstruktor ? Die allgemeine Container klasse oder die beiden erbenden oder haben alle einen ?  Und kann man "40ft und 40ftHC" als enum darstellen bzw ist das sinnvoll ?


----------



## Noob1234_1234 (15. Jan 2020)

Meine Terminalklasse sollte ja eigentlich keine Attribute besitzen außer den Kran und ggnf eine Datenstruktur zum Speichern der Stacks besitzen oder ? 
Sonst hat sollte sie eine oder zwei Methoden bekommen? ( bin mir nicht sicher, ob eine Methode alle Paramter entgegennimmt oder nicht) Könnt ihr mir jetzt bitte verraten, wie ihr euch das mit den 2 Integern für den Transport vorgestellt habt ?


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Alles was nicht in der Aufgabe steht überleg ich mir erst, wenn ich die Aufgabe fertig habe


Musst Du wissen.



Noob1234_1234 hat gesagt.:


> aber eine Frage welche Klasse besitzt den Konstruktor ?


Jede Klasse besitzt einen Konstruktor.



Noob1234_1234 hat gesagt.:


> Und kann man "40ft und 40ftHC" als enum darstellen bzw ist das sinnvoll ?


Wozu?



Noob1234_1234 hat gesagt.:


> Meine Terminalklasse sollte ja eigentlich keine Attribute besitzen außer den Kran und ggnf eine Datenstruktur zum Speichern der Stacks besitzen oder ?


Das weiß ich noch nicht. Zum aktuellen Stand besitzt die Klasse eben die beiden Attribute.



Noob1234_1234 hat gesagt.:


> Sonst hat sollte sie eine oder zwei Methoden bekommen? ( bin mir nicht sicher, ob eine Methode alle Paramter entgegennimmt oder nicht) Könnt ihr mir jetzt bitte verraten, wie ihr euch das mit den 2 Integern für den Transport vorgestellt habt ?


Du könntest dem ContainerTerminal eine Methode spendieren:

```
public void transportContainer(int originStackId, int destinationStackId)
```


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Musst Du wissen.
> 
> 
> Jede Klasse besitzt einen Konstruktor.
> ...


Eben zum letzteren, soweit hatte ich sie auch schon, aber was passiert mit den 2 mitgegebenen integern? Das war ja schon heute morgen und gestern mein größtes Problem. Ich hatte ja etwas, dass geklappt hatte, aber eben nicht der Aufgabe entsprechend, also falsch.

Wie würdest du es denn mit den 2 Typen machen? Es gibt ja nur nur die 40ft und 40ftHC und die werden auch per Textdatei mitgegeben? ich habs gerade mit Strings ? 

Und zu dem Thema Konstruktor. Ich weiß, dass jede Klasse einen Konstruktor hat, aber zum Bsp beim Kran hab ich ja auch keine weiteren Spezifikationen getroffen ?


----------



## Noob1234_1234 (15. Jan 2020)

Und haben die erbenden Klassen überhaupt einen Zweck oder sind sie nur wegen der Aufgabenstellung da ?


----------



## Noob1234_1234 (15. Jan 2020)

Oder muss ich den Container Typ in den jeweiligen Klassen  einfach als finale definieren?


Noob1234_1234 hat gesagt.:


> Eben zum letzteren, soweit hatte ich sie auch schon, aber was passiert mit den 2 mitgegebenen integern? Das war ja schon heute morgen und gestern mein größtes Problem. Ich hatte ja etwas, dass geklappt hatte, aber eben nicht der Aufgabe entsprechend, also falsch.
> 
> Wie würdest du es denn mit den 2 Typen machen? Es gibt ja nur nur die 40ft und 40ftHC und die werden auch per Textdatei mitgegeben? ich habs gerade mit Strings ?
> 
> Und zu dem Thema Konstruktor. Ich weiß, dass jede Klasse einen Konstruktor hat, aber zum Bsp beim Kran hab ich ja auch keine weiteren Spezifikationen getroffen ?


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Das war ja schon heute morgen und gestern mein größtes Problem. Ich hatte ja etwas, dass geklappt hatte, aber eben nicht der Aufgabe entsprechend, also falsch.


Schau Dir das Diagramm aus #101 an: was könnte man mit den Integern anstellen?



Noob1234_1234 hat gesagt.:


> Wie würdest du es denn mit den 2 Typen machen? Es gibt ja nur nur die 40ft und 40ftHC und die werden auch per Textdatei mitgegeben? ich habs gerade mit Strings ?


Meinst Du für die Initialisierung des Terminals? Prüfen, welcher String es ist und dann ein Objekt der entsprechenden Klasse erstellen.



Noob1234_1234 hat gesagt.:


> Ich weiß, dass jede Klasse einen Konstruktor hat, aber zum Bsp beim Kran hab ich ja auch keine weiteren Spezifikationen getroffen ?


s. Diagramm aus #101. Das "#" vor dem Konstruktor bedeutet übrigens "protected".


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Schau Dir das Diagramm aus #101 an: was könnte man mit den Integern anstellen?
> 
> 
> Meinst Du für die Initialisierung des Terminals? Prüfen, welcher String es ist und dann ein Objekt der entsprechenden Klasse erstellen.
> ...



Ja ich weiß, dass ich über getContainerStackID über die ID zugreifen kann und diese mit den per Textdatei gegebenen vergleichen kann/ muss, aber wie initialisier ich denn den Containerstack? Es muss doch alles in eine Methode gepackt werden oder ?
quasi so ?

```
public void terminalDoWorkContainer(String containertyp, int id, int weight, int stacknumber, int origin,
            int destination) {

        ContainerStack cs0 = new ContainerStack(stacknumber);
        cs0.place(new Container40ft(containertyp, id, weight));
        Terminal.printLine(cs0);

    }
```
 
    oder ist der Vorgang des Erstellens der Stacks und der Vorgang des Transports unabhängig voneinader ?
    also 2 methoden?
    Eine müsste dann so aussehen und die andere so :


```
public void terminalDoWorkContainer(String containertyp, int id, int weight, int stacknumber)
```
 
    bzw

```
public void terminalTransportContainer(int origin, int destination) {

    }
```


----------



## mrBrown (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> oder ist der Vorgang des Erstellens der Stacks und der Vorgang des Transports unabhängig voneinader ?
> also 2 methoden?


Ja.


----------



## Noob1234_1234 (15. Jan 2020)

Wenn ich mich nicht ganz irre sollte es so eigentlich aussehen ? Also der Transport oder

```
public class ContainerTerminal {

    final Crane crane = new Crane();

    ContainerStack cs = new ContainerStack(0);
    ContainerStack cs2 = new ContainerStack(0);

    public void terminalTransportContainer(int origin, int destination) {
        if (cs.getContainerStackID() == origin) {
            crane.moveTo(cs);
            crane.pick();
            if (cs2.getContainerStackID() == destination) {
                crane.moveTo(cs2);
                crane.place();
            }
        }

    }
```

Edit : Aber hier hab ich von vornerein die Stacks festgelegt und ich glaub das ist nicht der Sinn der Sache ? Also doch alles in eine Methode oder ?


----------



## mrBrown (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Wenn ich mich nicht ganz irre sollte es so eigentlich aussehen ? Also der Transport oder


Vermutlich hast du mehr als zwei Container-Stapel, oder?



Noob1234_1234 hat gesagt.:


> Falls die tatsächlich erreichbare Hubhöhe geringer als die Höhe des Zielstapels ist, ist es dem Kran nicht möglich, den Container auf dem Zielstapel zu platzieren. Der Container wird in diesem Fall gar nicht erst vom Ursprungsstapel entnommen.


BTW, diesen Teil musst du beim Transport auch noch berücksichtigen.


----------



## Meniskusschaden (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Meniskusschaden hat gesagt.:
> 
> 
> > Na ja, nehmen wir mal an, der Kran kann maximal 10m, der Stapel hat gerade 6m und der Container ist 2m hoch. Nach deiner Formel könnte der Kran das dann nicht machen, weil `10m - 6m >= 6m` false ergibt.
> ...


Tja, was soll man da noch übersetzen? Du hast einen Stapel mit bekannter Höhe und beabsichtigst einen Container mit ebenfalls bekannter Höhe darauf zu stellen. Beides zusammen darf eben nicht größer als die vorgegebene maximale Höhe sein. Das ist schon das ganze Geheimnis.


Noob1234_1234 hat gesagt.:


> Bin immernoch der Meinung, dass meine Formel stimmen muss, wobei du gerade ja gezeigt hast, dass es nicht sein kann


Wenn du überzeugt bist, dass deine Formel stimmt, solltest du auch dabei bleiben. Vielleicht habe ich sie ja falsch verstanden.


----------



## Noob1234_1234 (15. Jan 2020)

Meniskusschaden hat gesagt.:


> Tja, was soll man da noch übersetzen? Du hast einen Stapel mit bekannter Höhe und beabsichtigst einen Container mit ebenfalls bekannter Höhe darauf zu stellen. Beides zusammen darf eben nicht größer als die vorgegebene maximale Höhe sein. Das ist schon das ganze Geheimnis.
> 
> Wenn du überzeugt bist, dass deine Formel stimmt, solltest du auch dabei bleiben. Vielleicht habe ich sie ja falsch verstanden.


Jetzt aber ?

```
public void pick() {
        if (testHeight() == true) {
            if (MAXHEIGHT >= (position.calculateContainerStackHeight() + containerLoad.getHeight())) {
                while (position.stack.size() < 1) {
                    containerLoad = position.pick();
                }
            }
        }
    }
```


----------



## Noob1234_1234 (15. Jan 2020)

mrBrown hat gesagt.:


> Vermutlich hast du mehr als zwei Container-Stapel, oder?
> 
> 
> BTW, diesen Teil musst du beim Transport auch noch berücksichtigen.



Hab ich den Teil nicht hiermit berücksichtigt?

```
public boolean testHeight() {
        if ((MAXHEIGHT - position.calculateContainerStackHeight()) >= MAXHEIGHT) {
            position.place(containerLoad);
            return true;
        }
        return false;
    }
    
    public void pick() {
        if (testHeight() == true) {
            if (MAXHEIGHT >= (position.calculateContainerStackHeight() + containerLoad.getHeight())) {
                while (position.stack.size() < 1) {
                    containerLoad = position.pick();
                }
            }
        }
    }
```

Es wird zuerst geprüft, ob man ihn absetzen könnte. Wenn das false ist bzw nicht geht, wird der Vorgang gar nicht erst gestartet ?


----------



## Noob1234_1234 (15. Jan 2020)

Kann mir bitte noch enden um das Thema abzuhacken.  Ich hab jetzt als Ansatz eine Hashmap benutzt. Als Key hab ich die stacknummer gesetzt, somit kann es keine Duplikate geben oder ? Aber wie geh ich jetzt weiter vor ? Bei der ersten Methode des Terminals sollen jetzt Container auch gesetzt werden, aber wie ? Muss ich die Container Konstruktoren in die ContainerStack Konstruktor packen?


```
import java.util.HashMap;
import java.util.List;
import edu.kit.informatik.Terminal;

public class ContainerTerminal {

    final Crane crane = new Crane();

    HashMap<Integer, ContainerStack> hm = new HashMap<Integer, ContainerStack>();

    public void terminalDoWorkContainer(String containertyp, int id, int weight, int stacknumber) {

        hm.put(stacknumber, new ContainerStack(stacknumber));
        cs.place(new Container40ft(containertyp, id, weight));

    }

    public void terminalTransportContainer(int origin, int destination) {

        if (cs.getContainerStackID() == origin) {
            crane.moveTo(cs);
            crane.pick();
            Terminal.printLine(cs);
            if (cs2.getContainerStackID() == destination) {
                crane.moveTo(cs2);
                crane.place();
                Terminal.printLine(cs2);
            }
        }

    }
```

Oder hat jemand eine bessere Idee als Hashmap ???? Set?


----------



## Meniskusschaden (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Jetzt aber ?
> 
> ```
> public void pick() {
> ...


Sagen wir mal so: wenn es nicht sowieso schon falsch wäre, wäre es vielleicht richtig.
Laut folgendem Ausschnitt:


Noob1234_1234 hat gesagt.:


> Falls die tatsächlich erreichbare Hubhöhe geringer als die Höhe des Zielstapels ist, ist es dem Kran nicht möglich, den Container auf dem Zielstapel zu platzieren. Der Container wird in diesem Fall gar nicht erst vom Ursprungsstapel entnommen.


soll der Container nicht entnommen werden, wenn er sowieso nicht am Ziel abgelegt werden kann. containerLoad referenziert also noch gar nicht den fraglichen Container. Außerdem machst du das ganze in der pick-Methode, also bevor du überhaupt zum Ziel gefahren bist. Somit referenziert position zu diesem Zeitpunkt auch nicht den Zielstapel.
Der Sinn der Schleife erschließt sich mir nicht.
Was ist der Zweck von testHeight()? Zu prüfen, ob der Kran überhaupt hoch genug ist, um den Container  vom Ursprungsstapel zu heben?


----------



## mrBrown (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Es wird zuerst geprüft, ob man ihn absetzen könnte. Wenn das false ist bzw nicht geht, wird der Vorgang gar nicht erst gestartet ?


Nein, der Code ist ziemlicher Unsinn.

Mach dir mal bildlich klar, was dort passiert:

Es wird pick aufgerufen (also, Container aufheben).
Das ruft testHeight auf, und testHeight prüft er dann irgendwelchen Unsinn (siehe den Hinweis von @Meniskusschaden) und setzt irgendeinen Container auf den aktuellen Stapel.
Wenn die merkwürdige Bedingung zutrifft, prüfst du das Gewicht (wobei du Gewicht und Höhe zusammen rechnest?!) und hebst den Container auf.

Oder in kurz: Wenn völlig unsinnige Bedingungen zutreffen, stellst du irgendeinen Container auf den Stapel und hebst diesen Container dann wieder auf.





Noob1234_1234 hat gesagt.:


> Kann mir bitte noch enden um das Thema abzuhacken.


Bevor du das Thema abhaken kannst, solltest du zumindest ein grundlegendes Verständnis des Problems und des Codes, den du selber schreibst, haben...


----------



## Noob1234_1234 (15. Jan 2020)

Och leute, 
bitte ich flehe euch an. Könnt ihr mir dieses eine Mal helfen die Aufgabe fertigzustellen, keine Rätsle mehr nichts. Ich muss dieses Projekt morgen früh fertig haben und mit früh meine ich 6 Uhr. Bitte bitte ich will es nicht mal perfekt haben, aber soll diese Textdatei lesen. Also können wir bitte die Schönheitsop des Codes lassen und einfach zur Sache kommen. Bitteeee Leute bitte. Ich bin kurz vor einem Nervenkollaps, hab jetzt gleich noch eine Klausur und hab schon geheult deswegen. Bitte? 
Wenn ihr net helfen wollen, dann sagts bitte direkt, aber ich muss das sputen und ich weiß, dasss was ich sage ist egoistisch und frech, aber wirklich ich fleheee euch alle an. Bitte sagt mir einfach, was ich tun soll. 
Bitte oder eben nicht


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Ich hab jetzt als Ansatz eine Hashmap benutzt.


Genügt die? Wie soll denn das Terminal inkl. Kran aussehen? Ich hätte mir etwas vorgestellt wie im Bild unter https://sp.depositphotos.com/185974182/stock-photo-cargo-container-shipping-terminal.html zu sehen ist.


----------



## Noob1234_1234 (15. Jan 2020)

Alle Kleinigkeiten sind egal, das Programm bekommt diese Eingabe 
40ft;100;20000kg;0
40ftHC;200;30000kg;0
40ft;300;22000kg;1
40ft;400;19000kg;1
40ft;500;20000kg;1
40ft;600;22000kg;2
40ftHC;700;28000kg;3
--
2;0
3;2

und soll das hier liefern:
40ft;100;20000kg;0
40ftHC;200;30000kg;0
40ft;600;22000kg;0
40ft;300;22000kg;1
40ft;400;19000kg;1
40ft;500;20000kg;1
40ftHC;700;28000kg;2

Bitte leute nur das. Ich brauch es wirklich dringend. Egal wie, hauptsache das kommt bei raus. Bitte postet mir wie ich meinen Code aufbauen soll, Ich verzweifle und will doch nur mal wieder atmen können. Ich bin euch für die Hilfe bis hier sehr dankbar, aber können wir es bitte vollenden. Wirklich ich hab das Haus tagelang nicht verlassen und kann das am Ende nicht abgeben, Ich bin noch ein absoluter Java Noob, aber bitte bitte bitte, Spoilert mich


----------



## Noob1234_1234 (15. Jan 2020)




----------



## mihe7 (15. Jan 2020)

Ja, das entspricht dem, was ich mir vorgestellt hätte. Da würde ich mich fragen, wie man von Stapel 0 zu Stapel 2 kommt, wenn Stapel 1 höher als die maximale Hubhöhe ist...



Noob1234_1234 hat gesagt.:


> Egal wie, hauptsache das kommt bei raus.


OK:

```
System.out.println("40ft;100;20000kg;0\n" +
    "40ftHC;200;30000kg;0\n" +
    "40ft;600;22000kg;0\n" +
    "40ft;300;22000kg;1\n" +
    "40ft;400;19000kg;1\n" +
    "40ft;500;20000kg;1\n" +
    "40ftHC;700;28000kg;2");
```


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Ja, das entspricht dem, was ich mir vorgestellt hätte. Da würde ich mich fragen, wie man von Stapel 0 zu Stapel 2 kommt, wenn Stapel 1 höher als die maximale Hubhöhe ist...
> 
> 
> OK:
> ...



Ja so hab ich mir das nicht vorgestellt hahaha. ich kann die Textdatei über die Kommandozeile lesen und in einzelne Teile aufteilen, also in Zeilenform (s[0] würde so aussehen = 40ft;100;20000kg;0), aber *erste Frage splitte ich ein Array, so dass ich nur die Einzelteile bekomme außer das kg?????

Zweite Frage:* Will mir jmd jetzt verratenm wie meine Methoden heißen und was sie machen bzw entgegennehmen müssen oder nicht? Bitteeee Leute bitte. ich weiß ich bin scheiße aber bitte ich brauch euch


```
public class ContainerTerminal {

    final Crane crane = new Crane();

    HashMap<Integer, ContainerStack> hm = new HashMap<Integer, ContainerStack>();

    public void terminalDoWorkContainer(String containertyp, int id, int weight, int stacknumber) {

        hm.put(stacknumber, new ContainerStack(stacknumber));
        cs.place(new Container40ft(containertyp, id, weight));

    }

    public void terminalTransportContainer(int origin, int destination) {

        if (cs.getContainerStackID() == origin) {
            crane.moveTo(cs);
            crane.pick();
            Terminal.printLine(cs);
            if (cs2.getContainerStackID() == destination) {
                crane.moveTo(cs2);
                crane.place();
                Terminal.printLine(cs2);
            }
        }

    }
```


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Ja, das entspricht dem, was ich mir vorgestellt hätte. Da würde ich mich fragen, wie man von Stapel 0 zu Stapel 2 kommt, wenn Stapel 1 höher als die maximale Hubhöhe ist...


Das ist unwichtig für die Aufgabe. Es ist nur ein vereinfachtes Modell. Bitte du scheinst wirklich sehr schlau zu sein. Bitte sag mir wie die Methoden auszusehen haben, damit es zumindest in Theorie klappt 
OK:

```
System.out.println("40ft;100;20000kg;0\n" +
    "40ftHC;200;30000kg;0\n" +
    "40ft;600;22000kg;0\n" +
    "40ft;300;22000kg;1\n" +
    "40ft;400;19000kg;1\n" +
    "40ft;500;20000kg;1\n" +
    "40ftHC;700;28000kg;2");
```
[/QUOTE]


----------



## Noob1234_1234 (15. Jan 2020)

Und falls irgendwer helfen will ich erwarte keine perfekten lösungen. Ich würde auch nur 3 Stacks initialisieren und das programm machen lassen, hauptsache der Transport und die 2 oder 1 methode funktionieren. Bitte Leute


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> erste Frage splitte ich ein Array, so dass ich nur die Einzelteile bekomme außer das kg?????


?!?

```
String[] einzelteile = zeile.split(";");
```
Das 2-te Element scheint auf "kg" enden zu müssen. Aber: Du fuchtelst schon wieder an der nächsten Baustelle rum, ohne den Transport erledigt zu haben.

Jetzt kümmern wir uns erstmal die Methode terminalTransportContainer, die bekommt zwei Stapelnummern. Du hast eine Map, mit der Du anhand der Stapelnummer den Stapel ermitteln kannst. Schreib das mal vernünftig um.


----------



## Noob1234_1234 (15. Jan 2020)

Ich bin verzweifet deswegen fuchtel ich überall rum und kurz vorm zusammenbruch.

Meine Problem ist jetzt, dass ich die ContaineStacks in der Map speicher, also müsste ich doch in der Methode TransportContainer durch die Map iterrieren oder bis die Nummer zu einem Key passt? aber wie zum Teufel geht das


```
public class ContainerTerminal {

    final Crane crane = new Crane();

    HashMap<Integer, ContainerStack> hm = new HashMap<Integer, ContainerStack>();

    public void terminalDoWorkContainer(String containertyp, int id, int weight, int stacknumber) {

        hm.put(stacknumber, new ContainerStack(stacknumber));
        cs.place(new Container40ft(containertyp, id, weight));

    }

    public void terminalTransportContainer(int origin, int destination) {

        if (cs.getContainerStackID() == origin) {
            crane.moveTo(cs);
            crane.pick();
            Terminal.printLine(cs);
            if (cs2.getContainerStackID() == destination) {
                crane.moveTo(cs2);
                crane.place();
                Terminal.printLine(cs2);
            }
        }

    }
```


----------



## mihe7 (15. Jan 2020)

Noch was: Du hast anscheinend einen falschen Eindruck. Es ist nicht so, dass wir die Aufgabenstellung lesen und dann in fünf Minuten fertigen Code hinschreiben. Wir müssen das Problem, genauso wie Du, analysieren, um es zu verstehen, modellieren, uns wieder korrigieren usw. Darum heißt es auch Software-_Entwicklung_ und nicht Software-_Produktion_. 



Noob1234_1234 hat gesagt.:


> durch die Map iterrieren oder bis die Nummer zu einem Key passt? aber wie zum Teufel geht das


Eine Map bildet einen Schlüssel auf einen Wert ab. Das hat den Vorteil, dass man über den Schlüssel direkt den Wert erhält. Dazu bietet die Map eine Methode get an... Und gib hm einen vernünftigen Namen, z. B. stacks (oder containerStacks).


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Noch was: Du hast anscheinend einen falschen Eindruck. Es ist nicht so, dass wir die Aufgabenstellung lesen und dann in fünf Minuten fertigen Code hinschreiben. Wir müssen das Problem, genauso wie Du, analysieren, um es zu verstehen, modellieren, uns wieder korrigieren usw. Darum heißt es auch Software-_Entwicklung_ und nicht Software-_Produktion_.


Ihr seid trotzdem allesamt wirklich krass

Eine Map bildet einen Schlüssel auf einen Wert ab. Das hat den Vorteil, dass man über den Schlüssel direkt den Wert erhält. Dazu bietet die Map eine Methode get an... Und gib hm einen vernünftigen Namen, z. B. stacks (oder containerStacks).
[/QUOTE]


```
if (stacks.containsKey(origin)) {
            crane.moveTo(stacks.); // hier ist das Problem, ich weiß, dass es ein Befehl gibt über den ich über den Key auf das Objekt zugreifen kann, aber ich find ihn nicht
            crane.pick();
            Terminal.printLine(cs);
            if (cs2.getContainerStackID() == destination) {
                crane.moveTo(cs2);
                crane.place();
                Terminal.printLine(cs2);
            }
        }
```


----------



## Noob1234_1234 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Ihr seid trotzdem allesamt wirklich krass
> 
> Eine Map bildet einen Schlüssel auf einen Wert ab. Das hat den Vorteil, dass man über den Schlüssel direkt den Wert erhält. Dazu bietet die Map eine Methode get an... Und gib hm einen vernünftigen Namen, z. B. stacks (oder containerStacks).




```
if (stacks.containsKey(origin)) {
            crane.moveTo(stacks.); // hier ist das Problem, ich weiß, dass es ein Befehl gibt über den ich über den Key auf das Objekt zugreifen kann, aber ich find ihn nicht
            crane.pick();
            Terminal.printLine(cs);
            if (cs2.getContainerStackID() == destination) {
                crane.moveTo(cs2);
                crane.place();
                Terminal.printLine(cs2);
            }
        }
```
[/QUOTE]
Edit : Ich hab die methode


----------



## Noob1234_1234 (15. Jan 2020)

Soooo müsste es doch klappen in der Theorie (vorausgesetzt meine Befehle und alles sind top) 


```
public void terminalTransportContainer(int origin, int destination) {

        if (stacks.containsKey(origin)) {
            crane.moveTo(stacks.get(origin));
            crane.pick();

            if (stacks.containsKey(destination)) {
                crane.moveTo(stacks.get(destination));
                crane.place();

            }
        }

    }
```


----------



## Noob1234_1234 (15. Jan 2020)

Und der andere muss irgendwie so aussehen : Aber es fehlt die Überprüfung ob es schon einen Stack mit er Nummer gibt i guess


```
public void terminalDoWorkContainer(String containertyp, int id, int weight, int stacknumber) {

        ContainerStack containerstack = new ContainerStack(stacknumber);
        stacks.put(stacknumber, containerstack);

        containerstack.place(new Container40ft(containertyp, id, weight));

    }
```


----------



## Noob1234_1234 (15. Jan 2020)

Ich schreib zwar die ganze Zeit nur mit mir aber ich glaube ich habe jetzt einen gesundaussehenden Code für das Terminal


```
public class ContainerTerminal {

    final Crane crane = new Crane();

    HashMap<Integer, ContainerStack> stacks = new HashMap<Integer, ContainerStack>();

    public void terminalDoWorkContainer(String containertyp, int id, int weight, int stacknumber) {
        if (!stacks.containsKey(stacknumber)) {
            ContainerStack containerstack = new ContainerStack(stacknumber);
            containerstack.place(new Container40ft(containertyp, id, weight));
            stacks.put(stacknumber, containerstack);
        } else {
            stacks.get(stacknumber).place(new Container40ft(containertyp, id, weight));

        }

    }

    public void terminalTransportContainer(int origin, int destination) {

        if (stacks.containsKey(origin)) {
            crane.moveTo(stacks.get(origin));
            crane.pick();

            if (stacks.containsKey(destination)) {
                crane.moveTo(stacks.get(destination));
                crane.place();

            }
        }

    }
```


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Ich schreib zwar die ganze Zeit nur mit mir


Scheint zu helfen  

Ich frage mich gerade, was das ganze hier mit Vererbung zu tun haben soll... (s. Titel).


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Scheint zu helfen
> 
> Ich frage mich gerade, was das ganze hier mit Vererbung zu tun haben soll... (s. Titel).



Frag mich net. Die Aufgabe ist im Kontext Verrbung gestellt worden und ich weiß es auch net, wobei es ja die 2 Arten Container gibt und eigentlich muss ich irgendwie die entssprechenden Konstruktoren aufrufen, aber das mach ich nicht. Ich gebe einfach den Typ als String mit und joa wobei ich ja sogar eine Exception schreiben könnte, die alles ablehnt außer "40ft" und "40ftHC" aber ich lass es glaub ich. 

Ich brauch nur noch eine toStringMethode für das Terminal und dann muss ich doch noch am Kran und den Befehlen korrigieren oder kannst du mir kurz sagen, was ich falsch habe bei pick und den Bedingungen?


----------



## Noob1234_1234 (15. Jan 2020)

Wie mach ich das aber jetzt mit der toString methode ? irgendwie klappt das nicht


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Die Aufgabe ist im Kontext Verrbung gestellt worden und ich weiß es auch net, wobei es ja die 2 Arten Container gibt und eigentlich muss ich irgendwie die entssprechenden Konstruktoren aufrufen, aber das mach ich nicht.


Ja, mit Gewalt kann man natürlich Vererbung einbauen - haben wir im Modell auch gemacht. Dann musst Du beim Einlesen den Typ (String) prüfen und je nachdem die entsprechende Klasse auswählen. Nur ergibt das keinen Sinn, denn Vererbung dient dazu, Funktionalität zu ändern bzw. zu erweitern und daran ändert sich zwischen den Containerarten nichts.



Noob1234_1234 hat gesagt.:


> was ich falsch habe bei pick und den Bedingungen?


Du musst prüfen, ob Du der Kran bereits eine Ladung hat.



Noob1234_1234 hat gesagt.:


> Wie mach ich das aber jetzt mit der toString methode ? irgendwie klappt das nicht


Was meinst Du?


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Ja, mit Gewalt kann man natürlich Vererbung einbauen - haben wir im Modell auch gemacht. Dann musst Du beim Einlesen den Typ (String) prüfen und je nachdem die entsprechende Klasse auswählen. Nur ergibt das keinen Sinn, denn Vererbung dient dazu, Funktionalität zu ändern bzw. zu erweitern und daran ändert sich zwischen den Containerarten nichts.
> 
> 
> Du musst prüfen, ob Du der Kran bereits eine Ladung hat.


Bitte sag mir wie. Die Abgabe kommt näher und näher und ich schätze mal, dass ihr auch net die ganze Nacht da seid

Was meinst Du?
[/QUOTE]
Wie printe ich meine Hashmap aus ?


----------



## Noob1234_1234 (15. Jan 2020)

Hier zurück zur Kran Klasse, kann mir bitte wer sagen wo die Fehler liegen und wie ich sie behebe


```
public class Crane {

    private static final int MAXHEIGHT = 1920; // Zoll
    private static final int MAXLOADCAPACITY = 30000; // in kg
    private ContainerStack position; // aktuelle Position des Krans
    private Container containerLoad;

    public static int getMaxheight() {
        return MAXHEIGHT;
    }

    public static int getMaxloadcapacity() {
        return MAXLOADCAPACITY;
    }

    public void moveTo(ContainerStack stack) {
        position = stack;
    }

    public void pick() {

        //if (MAXHEIGHT >= (position.calculateContainerStackHeight() + containerLoad.getHeight())) {
           // while (position.stack.size() < 1) {
                containerLoad = position.pick();
            //}
       // }
    }

    public void place() {
        if (MAXHEIGHT >= (position.calculateContainerStackHeight() + containerLoad.getHeight())) {
            position.place(containerLoad);
        }
    }

    public boolean testHeight() {
        if ((MAXHEIGHT - position.calculateContainerStackHeight()) >= MAXHEIGHT) {
            position.place(containerLoad);
            return true;
        }
        return false;
    }

}
```


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Bitte sag mir wie.


Ernsthaft jetzt? Welchen Wert hat denn containerLoad unmittelbar nach Erzeugung des Krans?


----------



## Noob1234_1234 (15. Jan 2020)

mihe7 hat gesagt.:


> Ernsthaft jetzt? Welchen Wert hat denn containerLoad unmittelbar nach Erzeugung des Krans?



Oh 0 oder nicht? haha


```
public void pick() {

        if (MAXHEIGHT >= (position.calculateContainerStackHeight() + containerLoad.getHeight())) {
            if (containerLoad.getWeight() == 0) {
                containerLoad = position.pick();
            }
        }
    }
```

Aber passt sonst alles mehr oder weniger ? Also in der Kranklasse oder blockiert noch etwas den Transport, unabhängig von den Bedingugnen


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Oh 0 oder nicht?


OMG. Schon mal was von einer null-Referenz oder einer NullPointerException gehört?



Noob1234_1234 hat gesagt.:


> Aber passt sonst alles mehr oder weniger ?


Wenn Du nur Container mit einem Gewicht von 0 kg hochheben willst und Dir es egal ist, ob Du vor einem leeren Stapel stehst...

Mal ein paar Ideen:

```
if (position == null) {
    // Fehler: Kran steht vor keinem Stapel
}
if (position.isEmpty()) {
    // Fehler: Kran steht vor leerem Stapel
}
if (containerLoad != null) {
    // Fehler: am Kran hängt schon ein Container
}
if (position.calculateContainerStackHeight() > MAX_HEIGHT) {
    // Fehler: der Stapel ist höher als der Kran
}
```
EDIT: Hinzu käme natürlich noch das Gewicht.


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Wie printe ich meine Hashmap aus ?




```
public void print() {
    for (ContainerStack stack : stacks.values()) {
        System.out.println(stack);
    }
}
```


----------



## Noob1234_1234 (15. Jan 2020)

Danke erstmal dafür, Ich werd das gleich umsetzen, aber mein ContainerTerminal bzw die Hashmap funktioniert glaub ich nicht.


```
ct.terminalDoWorkContainer("40ft", 100, 200, 2);
        ct.terminalDoWorkContainer("40ftHC", 100, 200, 1);

        Terminal.printLine(ct.stacks.get(2));
        Terminal.printLine(ct.stacks.get(1));  // Terminal.printLine ist mehr oder weniger das gleiche wie system.out
```

Ausgaben : 2 mal das gleiche, aber wieso???
40ftHC;100;200kg;1
40ftHC;100;200kg;1

Das Stappeln bei gleichen Nummern klappt jedoch, also immerhin etwas, aber wieso klappt das nicht mit der hashmap und dem erstellen und printen von stacks?

Edit : Stappeln ist anscheinend doch nicht das richtige, also hab ich es weg gemacht,


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Ausgaben : 2 mal das gleiche, aber wieso???


Keine Ahnung, da müsste man auch den Code z. B. zu ContainerStack sehen.


----------



## Noob1234_1234 (15. Jan 2020)

Egal ich habs aufgegeben, aber herzliches Dank an euch alle. Mal sehen, was meine Abgabe bringt haha Aber ich hab jetzt tatsächlich einfach die Ausgabe, die auf dem Blatt erwartet war genommen und printen lassen. Passt so und jetzt heißt es  beten für mich


----------



## mihe7 (15. Jan 2020)

Noob1234_1234 hat gesagt.:


> Aber ich hab jetzt tatsächlich einfach die Ausgabe, die auf dem Blatt erwartet war genommen und printen lassen.


0 Punkte.


----------



## Javinner (16. Jan 2020)

Noob1234_1234 hat gesagt.:


> und jetzt heißt es beten für mich


...


----------



## mihe7 (16. Jan 2020)

Javinner hat gesagt.:


> ...


Das war aber ein kurzes Gebet


----------

