# [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...



## boss3D (14. April 2013)

*[JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Hi @ all!

Ich habe hier eine Java-Aufgabe, bei der ich nicht ganz verstehe, WAS zu machen ist. Wie das ganze dann code-mäßig aussehen soll, kann ich mir dann schon selbst überlegen (werden wir eh sehen, wie weit ich komme) ...




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



1.) Wie versteht ihr den ersten Punkt? Methoden für Addition, Subtraktion, Multiplikation und Division von römischen Zahlen erstellen? Wo die römischen und dezimalen Zahlen hernehmen? Einlesen per scanner oder gleich ein paar fix definieren?

2.) Ermittlung des numerischen Wertes ist klar. Einfach den dezimalen Wert zu einer beliebigen römischen Zahl ermitteln, nehme ich an?!

3.) Ermittlung der normalisierten Form bezieht sich dann wohl auf die Punkte 4 und 5?! Eine "falsche" römische Zahl gemäß den Regeln in Punkt 4 und 5 korrigieren?! Nur, wie das umsetzen? Das wird ja eine Raterei, welche römische Zahl der User gemeint haben könnte?!

4.) Und was kann ich mir dann unter der Anmerkung nach Punkt 5 vorstellen? Eine römische Zahl wird ja immer als Zeichenkette ein-/angegeben?! Das Gegenteil ist ja dann ein dezimaler int?! Und wieso soll da dann plötzlich eine "falsche" Zeichenkette nicht fehlerbereinigt werden?

^^ Blickt bei der Aufgabe irgendwer durch? 

Vielen Dank für baldige Antworten!


----------



## DarkMo (14. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*



boss3D schrieb:


> 1.) Wie versteht ihr den ersten Punkt? Methoden für Addition, Subtraktion, Multiplikation und Division von römischen Zahlen erstellen? Wo die römischen und dezimalen Zahlen hernehmen? Einlesen per scanner oder gleich ein paar fix definieren?


Na du liest halt meinetwegen ne römische 5 und ne römische 4 ein -> "V" und "IV". da haste schon deine römischen zahlen. die additions methode würde dann szs so aussehen:
string RomanNumber::addition(string a, string b) { ... }
am ende kommt wieder ein string bei raus -> V + IV = IX.



boss3D schrieb:


> 2.) Ermittlung des numerischen Wertes ist klar. Einfach den dezimalen Wert zu einer beliebigen römischen Zahl ermitteln, nehme ich an?!


richtig. das ist ein wichtiger schritt denke ich mal. also aus der "V" machst du ne 5 und aus der "IV" ne 4. eine umkehrfunktion wäre dann noch nicht übel. dann kannst du nämlich aus der additions methode sowas hier machen:
string RomanNumber::addition(string a, string b) { return this.dec2roman( this.roman2dec(a) + this.roman2dec(b) ); }
also, du wandelst die eingegebenen strings in dezimale zahlen um, rechnest mit denen das operations-ergebnis aus, und wandelst dieses wieder in ne römische ziffer (string) um.



boss3D schrieb:


> 3.) Ermittlung der normalisierten Form bezieht sich dann wohl auf die Punkte 4 und 5?! Eine "falsche" römische Zahl gemäß den Regeln in Punkt 4 und 5 korrigieren?! Nur, wie das umsetzen? Das wird ja eine Raterei, welche römische Zahl der User gemeint haben könnte?!


joa, normalisierte form... soll dann aus "ViIi" "VIII" werden? also nen einheitliches format durchgesetzt werden? wobei es da doch sicher string-methoden für gibt. .lower() oder so für alles in kleinbuchstaben. das mit der falschen römischen zahl ergibt sich doch aus der beschreibung, wie sich eine römische zahl zusammensetzt. also wenn einer für ne 4 IIII eingibt, ist das keine römische zahl -> diese soll dann eben in ein IV umgewandelt werden. oder eben das bsp mit der 99. die 99 wird nicht als IC (eins vor 100) dargestellt, sondern als XCIX (10 vor hundert + 1 vor 10 -> 100-10+10-1 quasi ^^). dann soll eben das falsche IC in ein richtiges XCIX umgewandelt werden. vom verständnis her nicht so schwer, das umzusetzen...



boss3D schrieb:


> 4.) Und was kann ich mir dann unter der Anmerkung nach Punkt 5 vorstellen? Eine römische Zahl wird ja immer als Zeichenkette ein-/angegeben?! Das Gegenteil ist ja dann ein dezimaler int?! Und wieso soll da dann plötzlich eine "falsche" Zeichenkette nicht fehlerbereinigt werden?


 hmm, hier weis ich grad nich so recht, wass du meinst ^^

aber generell glaube ich, will er hier was ganz anderes, als ich erst gedacht hab (un du vllt auch). wie es scheint, sollst du eine klasse bauen, die EINE zahl repräsentiert. von operationen wie addition seh ich da grad garnix auf anhieb. sprich, du müsstest eine klasse bauen, die einmal einen string und einmal einen int wert enthält sowie 3 konstruktoren -> einmal der default konstruktor (hier müsste dann "n. a." und 0 gespeichert werden, dann einmal ein konstruktor, der aus nem string das objekt erzeugt (also aus der römischen zahl ne dezimale macht - am besten per methode - und nebenbei noch die römische zahl ggf korrigiert) und zu guter letzt noch einen, der das objekt aus ner dezimalen zahl erstellt (also aus der zahl den string für die römische zahl erstellt und die zahl an sich einfach so speichert).

die ermittlung des numerischen wertes is ja dann schon geschehen - einfach den int wert ausgeben. die weitere frage bleibt natürlich, was ne normalisiert römische zahl sein soll ^^


vielleicht kommt ja als nächster schritt dann sowas, wie eigene operatoren entwickeln (hab ich selbst auch noch nie gemacht). wenn mans grundprinzip kennt, dürfte das aber auch wieder simpel sein: man erstellt einfach ein neues objekt der klasse das mit dem ergebnis der numerischen teile gebildet wird. wenn ich jetz konkret wüsste, wie das funzt, würd ich nen bsp liefern ^^


----------



## boss3D (14. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*



DarkMo schrieb:


> Na du liest halt meinetwegen ne römische 5 und ne römische 4 ein -> "V" und "IV". da haste schon deine römischen zahlen. die additions methode würde dann szs so aussehen:
> string RomanNumber::addition(string a, string b) { ... }
> am ende kommt wieder ein string bei raus -> V + IV = IX.


Wie Rechenmethoden zu schreiben wären, könnte ich mir schon vorstellen. Meine Frage ist eher, ob man überhaupt welche braucht ... oder ob da ganz was anderes gemeint ist ...

Was ist mit dem Satz gemeint: Erzeugung von römischen Zahlen [...] aus anderen römischen Zahlen. --> ??? Da hätte ich spontan auf Rechenmethoden getippt?!


DarkMo schrieb:


> aber generell glaube ich, will er hier was ganz anderes, als ich erst gedacht hab (un du vllt auch). wie es scheint, sollst du eine klasse bauen, die EINE zahl repräsentiert. von operationen wie addition seh ich da grad garnix auf anhieb. sprich, du müsstest eine klasse bauen, die einmal einen string und einmal einen int wert enthält sowie 3 konstruktoren -> einmal der default konstruktor (hier müsste dann "n. a." und 0 gespeichert werden, dann einmal ein konstruktor, der aus nem string das objekt erzeugt (also aus der römischen zahl ne dezimale macht - am besten per methode - und nebenbei noch die römische zahl ggf korrigiert) und zu guter letzt noch einen, der das objekt aus ner dezimalen zahl erstellt (also aus der zahl den string für die römische zahl erstellt und die zahl an sich einfach so speichert).


Ich schaue mal, wie weit ich das hinkriege. Mit Konstruktoren beschäftige ich mich seit ziemlich genau 2 Wochen ...


----------



## boss3D (14. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

So, mit ein Bisschen googeln habe ich jetzt mal folgendes für den Anfang zusammengebastelt:

```
public class RomanNumber {
    
    static String romanNum;
    static int decimalNum;
    static char convertToDecimal;
    
    [COLOR=royalblue]/**
     * @return calculated decimal decimalNum of a specific Roman number
     */    public int convertToDecimal() {  
        char lastChar=' ';
                
        for (int i=romanNum.length()-1; i>=0; i--) {
            switch (romanNum.charAt(i)) {
                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimalNum-=1;
                    } else {
                        decimalNum+=1;
                    }
                    break;
                case 'V':
                    decimalNum+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimalNum-=10;
                    } else {
                        decimalNum+=10;
                    }
                    break;
                case 'L':
                    decimalNum+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimalNum-=100;
                    } else {
                        decimalNum+=100;
                    }
                    break;
                case 'D':
                    decimalNum+=500;
                    break;
                case 'M':
                    decimalNum+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i);
            }

            
        return decimalNum;    
    }

}
```
Testen kann ich's aber leider nicht, weil's JUnit TestCase nicht so geht, wie ich mir das vorstelle:

```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class RomanNumberTest {
    
    private final String roman = "IV";
    
    @Test
    public void testConvertToDecimal() {
        assertEquals(roman.convertToDecimal(), 4);
    }
    
}
```
^^ Da sagt Eclipse: The method convertToDecimal() is undefined for the type String ???


----------



## DarkMo (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

ahso, ich glaub ich weis wieso. der erste code ist die roman klasse und die zweite die "main" die diese erste klasse aufruft?

in _RomanNumber _steht _static char convertToDecimal;_ - und dann die methode public int convertToDecimal(). also das sollte an sich schon probleme geben *denk*, dass ne variable und ne methode gleich benannt sind (wobei ers vllt noch unterscheiden könnt anhand der klammer hinterm namen). jedenfalls rufst du in deiner 2. klasse roman.convertToDecimal() auf - ohne ein roman-objekt überaupt erstelt zu haben. er kann in diesem falle also NUR auf static elemente der klasse zugreifen -> und das ist die char variable, welche du mit nem string penetrierst ^^ also zumindest vom grundkonzept her - was dieses assertEquals sein soll, weis ich grad nich so recht.

ok, JETZT hab ichs grad gesehn ^^ roman ist bei dir ja ein string, und für die klasse string ist keine methode convertToDecimal() festgelegt worden. du hast also tatsächlich ein roman-objekt, allerdings ist das eben vom typ string und nicht vom typ RomanNumber - deine klasse wird also garnich verwendet.

und konstruktoren sind ganz einfach:
die "bauen" - konstruieren eben - das objekt bei der erzeugung -> _RomanNumber roman;_ du erzeugst hier die variable _roman _vom typ _RomanNumber_. Jetzt werden speicherbereiche für die ganzen variablen erstellt, die zur klasse gehören - also hier eben _romanNum_, _decimalNum _und _convertToDecimal _(wozu auch immer du die hast ^^) - und das wars im groben mit dem standardkonstruktor (also auch wenn du selber keinen definierst, wird IMMER ein standard konstruktor bemüht - der kann halt nich sehr viel). in java wird alles glaube noch mit "0" initialisiert, das fehlt in c (wenn ichs richtig in erinnerung hab) zum bsp komplett - da steht also im zweifelsfall dann müll in der variablen ^^ der konstruktor hilft hier eben, das alles so zu initialisieren, wie man sich das wünscht. der konstruktor ist dabei eine methode, die einfach dem klassennamen entspricht:
RomanNumber() {}

damit haste schon deinen eigenen konstruktor gebaut - der ganusoviel kann, wie der default konstruktor  in unserem falle müsste der default konstruktor romanNum mit "n. a." und decimalNum mit 0 initialisieren - und fertig. da wir aber auch noch ein RomanNumber-objekt mit nem string oder nem int direkt erzeugen können wollen, sollten wir den noch überladen (überladen bedeuted, dass man die selbe funktion/methode (vom namen her) mehrfach definiert - sie müsen sich dann in der parameter liste unterscheiden):
RomanNumber(int dNum) {}
RomanNumber(string rNum) {}

bei den beiden wirds dann halt schon schwieriger. der übergebene teil wird einfach weiter gereicht (also this.decimalNum = dNum usw) und den anderen Teil muss man dann aus dem übergebenen generieren. ganz rudimentär kann man die 3 kontruktoren erstmal so definieren *denk* (weis jetz nich, inwiefern das java kompatibel is, geht mir eher ums prinzip ^^):

```
RomanNumber() {
    this.romanNum = "n. a.";
    this.decimalNum = 0;
}

RomanNumber(string rNum) {
    this.romanNum = rNum;
    this.convertToDecimal();
}

RomanNumber(int dNum) {
    this.decimalNum = dNum;
    this.convertToRoman();
}
```

elegant gelöst und das problem auf später verschoben xD natürlich müssten zumindest die funktionsrümpfe der convertfunken existieren, damits wenigstens läuft. jetzt könnte man also schonmal RomanNumber roman = new RomanNumber("IV"); schreiben, und ein roman-objekt mit der entsprechung der römischen 4 erstellen. die convertfunktionen wären dann das nächste problem. ne rückgabe brauchst du eigentlich nicht - aber du kannst ja gern wieder überladen und ne 2. erstellen, die nen wert übernimmt und einen zurückgibt. das als static deklariert, und du kannst diese umwandlung auch extern nutzen, ohne ein RomanNumber-objekt erstellen zu müssen. also als bsp sowas hier:

```
private void convertToDecimal() {
    this.decimalNum = this.convertToDecimal(this.romanNum);
}

static int convertToDecimal(string rNum) {
    // umwandlungscode
    // ...
}
```

hat den vorteil, dass du dann immer nur den code der static funktion ändern musst. würdest du den code in beiden methoden direkt schreiben, müsstest du bei änderungen beide anpassen - das soll ja nich sinn und zweck sein ^^ wie du siehst, wieder elegant gelöst - und dennoch keinen schritt weiter gekommen xD


----------



## boss3D (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Ok, danke erstmal!

Die Standarddinge, was Overloading ist und was Konstruktoren überhaupt sind, weiß ich eh. Im Moment sieht der Code so aus:

```
public class RomanNumber {
    
    private String romanNum;
    private int decimalNum;
    
    RomanNumber() {
        this.romanNum = "n. a.";
        this.decimalNum = 0;
    }

    RomanNumber(String rNum) {
        this.romanNum = rNum;
        this.convertToDecimal();
    }

    RomanNumber(int dNum) {
        this.decimalNum = dNum;
        this.convertToRoman();
    }
        
    /**
     * @return calculated decimal value of a specific Roman number
     */
    public int convertToDecimal() {  
        char lastChar=' ';
                
        for (int i=romanNum.length()-1; i>=0; i--) {
            switch (romanNum.charAt(i)) {
                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimalNum-=1;
                    } else {
                        decimalNum+=1;
                    }
                    break;
                case 'V':
                    decimalNum+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimalNum-=10;
                    } else {
                        decimalNum+=10;
                    }
                    break;
                case 'L':
                    decimalNum+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimalNum-=100;
                    } else {
                        decimalNum+=100;
                    }
                    break;
                case 'D':
                    decimalNum+=500;
                    break;
                case 'M':
                    decimalNum+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i);
            }

            
        return decimalNum;    
    }
    
    public void convertToRoman() {
        
    }

}
```
^^ Was ich noch gar nicht verstehe, ist, wann ich welches Attribut nehmen kann (final, static, privat, ...). Ich habe jetzt mal die Konstanten ganz oben auf nur _private_ geändert. Das müsste ja erstmal heißen, dass die nur in dieser Klasse sichtbar sind, was eh so passen müsste?! _final_ kann ich ja zumindest bei decimalNum nicht sagen, weil sich dessen Wert verändern können muss. Und wenn ich aber static sage, dann kommt in den Konstruktoren ein Warning: _The static field RomanNumber.decimalNum should be accessed in a static way. static _mag ich aber eh nicht und will ich möglichst vermeiden. ???

Und dann wäre da noch ein kleines Problemchen: Beim JUnit Test kommt raus, dass der sich "8" erwartet, als Ergebnis! Das verstehe ich überhaupt nicht, wenn ich mir den Code in der RomanNumber Klasse anschaue. Er sieht als erstes (von rechts beginnend) bei "IV" das "V" und rechnet 0+5=5. Dann geht er um eins nach links und sieht das "I". Dabei stellt er im Switch aber auch gleich fest, dass er rechts neben dem "I" ein "V" hat und rechnet daher 5-1=4 ... wieso erwartet sich der Test für "IV" also bitte "8"? 

```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class RomanNumberTest {
    
    @Test
    public void testConvertToDecimal() {
        RomanNumber roman = new RomanNumber("IV");
        assertEquals(4, roman.convertToDecimal());
    }
    
}
```
Mit _assertEquals_ kannst du BTW verschiedene Werte des gleichen Datentyps miteinander vergleichen. Z.B. 2 ints, so wie ich das hier vorhabe. Dabei ist der erste/linke Wert der erwartete und der zweite/rechte der eigentliche.

*[EDIT]*
Gerade gesehen: Bei "V" kommt er auch nicht auf "5", sondern auf "10"! Wieso kommt der immer auf's doppelte?


----------



## DarkMo (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

wegen public und final und was weis ich: beschränk dich (sofern du e nicht unbedingt brauchst) erstmal nur auf public und private. das ist noch recht simpel: public heisst, man kann von aussen direkt auf die variable zugreifen und private bedeuted, dass es nur aus der klasse selbst geändert werden kann. deine klasse hier is dafür sogar nen super bsp:

du hast hier 2 klassen-variablen, die eng miteinander verknüpft sind: roman und decimal teil. beide stellen die selbe zahl dar, nur in unterschiedlichen "systemen". würdest du die public machen, könnte man von aussen (also aus ner aufrufenden funktion/main...) einen der beiden werte ändern und würde den sinn zerstören -> also aus ner 4/IV ne 5/IV machen. aber 5 und IV sind nich mehr das selbe, alles im eimer *ausm fenster hüpf* ^^ mit private verhindert man das geschickt, da ein

```
RomanNumber rn = new RomanNumber(4);
rn.decimalNum = 5;
```
nicht mehr funktioniert. man muss hierfür dann halt "schnittstellen" bereitstellen. damit is ganz simpel ne methode zur manipulation gemeint. gern auch als getter oder setter bezeichnet glaube, weil man eben gern die namenskonvention getDecimalNum() oder eben setRomanNum(newRomanNum) usw nutzt. get returned einfach den wert, set überschreibts mit den übergebenen neuen wert. und bei der set kann man dann eben beide teile hier in einer weise ändern, dass die konsitenz(?) der klasse gewahrt bleibt. also private = zugriff nur mittels this.

static... der meckert warscheinlich, weil du statt this eher den klassen namen nehmen sollst. also statt this.convertToDecimal(this.romanNum); eben RomanNumber.convertToDecimal(this.romanNum);. static sorgt halt dafür, dass man diese methoden nutzen kann, ohne ein klassenobjekt erzeugen zu müssen. wird zum bsp gerade bei so math-klassen gern verwendet. math.sqrt(2); als bsp. hier wärs äusserst ätzend jedesmal erst nen mathe-objekt erschaffen zu müssen.

protected kenn ich noch vom namen her, das wars aber auch schon ^^ war glaube irgendwas wegen vererbung. aber da müsst ich jetz selber nachlesen. und final hab ich jetz auch nur schonmal von gehört. bedeutede das, dass man die bei ner vererbung in der subklasse nich überschreiben musste? abstract musste man ja zwangsläufig überschreiben. ach naja, da hörts bei mir auch auf ^^

ps: falls ich groben unfug schreib, könnt ihr mich gern berichtigen ^^


----------



## Supeq (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*



boss3D schrieb:


> 3.) Ermittlung der normalisierten Form bezieht sich dann wohl auf die Punkte 4 und 5?! Eine "falsche" römische Zahl gemäß den Regeln in Punkt 4 und 5 korrigieren?! Nur, wie das umsetzen? Das wird ja eine Raterei, welche römische Zahl der User gemeint haben könnte?!
> 
> 4.) Und was kann ich mir dann unter der Anmerkung nach Punkt 5 vorstellen? Eine römische Zahl wird ja immer als Zeichenkette ein-/angegeben?! Das Gegenteil ist ja dann ein dezimaler int?! Und wieso soll da dann plötzlich eine "falsche" Zeichenkette nicht fehlerbereinigt werden?
> 
> ...


 
ich springe einfach mal rein 

3) Ich würde hierfür einfach eine Methode "format_roman(string input_roman)" oder so ähnlich schreiben, die halt eine "römische Zahl" (auch in falscher Formatierung entgegennimmt), sie zunächst mit Hilfe deiner convertToDecimal() umwandelt, um sie dann mit convertToRoman wieder zurückzuwandeln und zurückzugeben.

Beispiel:

Eingabe: CCCCC
convertToDecimal(CCCCC) = 500
convertToRoman(500) = M

Ist eigentlich simpel, tricky wird es dann wenn mit der Subtraktionsregeln interpretiert werden soll. Da kann man dann wie du schon sagtest "raten welche römische Zahl gemeint ist" oder (mein Vorschlag) bei einer ungültigen Zahl (bsp.: IC) einfach eine Fehlermeldung ausgeben.


----------



## boss3D (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Als erstes würde ich mal gerne wissen, wieso ich immer genau das doppelte zurückbekomme  Für M 2000, für IV 8, ... ???

Bis mir das wer verraten kann, bastle ich jetzt mal eine convertToRoman Methode ...

*[EDIT]*
Codemäßig wäre ich wieder weiter, aber irgendwie funktioniert das alles nicht so, wie's soll ... 

```
public class RomanNumber {
    
    private String romanNum;
    private int decimalNum;
    
    [COLOR=royalblue]/**
     * Constructor
     * used if there's no display of a Roman number
     * or it's decimal value is 0
     */    RomanNumber() {
        this.romanNum = "n. a.";
        this.decimalNum = 0;
    }
    
    [COLOR=royalblue]/**
     * Constructor
     * used for the decimal representation of a Roman number
     * @param rNum is any Roman number
     */    RomanNumber(String rNum) {
        this.romanNum = rNum;
        this.convertToDecimal();
    }
    
 [COLOR=royalblue]   /**
     * Constructor
     * used for the Roman representation of a decimal integer
     * @param dNum is any integer number
     */    RomanNumber(int dNum) {
        this.decimalNum = dNum;
        this.convertToRoman();
    }
        
   [COLOR=royalblue] /**
     * @return calculated decimal value of a specific Roman number
     */    public int convertToDecimal() {  
        char lastChar=' ';
                
        for (int i=romanNum.length()-1; i>=0; i--) { [COLOR=seagreen]// begin at the right end of the string (= Roman number)            switch (romanNum.toUpperCase().charAt(i)) {[COLOR=seagreen] // check the char on each position                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimalNum-=1;
                    } else {
                        decimalNum+=1;
                    }
                    break;
                case 'V':
                    decimalNum+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimalNum-=10;
                    } else {
                        decimalNum+=10;
                    }
                    break;
                case 'L':
                    decimalNum+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimalNum-=100;
                    } else {
                        decimalNum+=100;
                    }
                    break;
                case 'D':
                    decimalNum+=500;
                    break;
                case 'M':
                    decimalNum+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i); [COLOR=seagreen]// after each round, make current index of the string to position of last char            }

            
        return decimalNum;    
    }
    
[COLOR=royalblue]    /**
     * @return calculated Roman number of a decimal integer
     */    public String convertToRoman() {        
        String roman="";
        int value=decimalNum;
        
        if (value==0) {
            return romanNum; [COLOR=seagreen]// in this case "n. a."        }

        if (value>=0) {
            while (value/1000 >= 1) { [COLOR=seagreen]// while division by 1000 is possible, do so                roman+="M";
                value-=1000;
            }
            if (value/900 >= 1) { [COLOR=seagreen]// if division by 1000 is no longer possible, continue with the next smaller integer                roman+="CM";
                value-=900;
            }
            if (value/500 >= 1) {
                roman+="D";
                value = value - 500;
            }
            if (value/400 >= 1) {
                roman+="CD";
                value-=400;
            }
            while (value/100 >= 1) { [COLOR=seagreen]// while division by 100 is possible, do so                roman+="C";
                value-=100;
            }
            if (value/90 >= 1) { [COLOR=seagreen]// if division by 100 is no longer possible, continue with the next smaller integer                roman+="XC";
                value-=90;
            }
            if (value/50 >= 1) {
                roman+="L";
                value-=50;
            }
            if (value/40 >= 1) {
                roman+="XL";
                value-=40;
            }
            while (value/10 >= 1) { [COLOR=seagreen]// while division by 10 is possible, do so                roman+="X";
                value-=10;
            }
            if (value/9 >= 1) {[COLOR=seagreen] // if division by 10 is no longer possible, continue with the next smaller integer                roman+="IX";
                value-=9;
            }
            if (value/5 >= 1) {
                roman+="V";
                value-=5;
            }
            if (value/4 >= 1) {
                roman+="IV";
                value-=4;
            }
            while (value >= 1) {
                roman+="I";
                value-=1;
            }
        }
        
        return roman;
    }

}
```
^^ Das Problem mit den doppelten Werten habe ich immer noch und bei folgendem JUnit TestCase ...

```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class RomanNumberTest {
    
    @Test
    public void testConvertToDecimal() {
        RomanNumber roman = new RomanNumber(0);
        assertEquals("n. a.", roman.convertToRoman());
    }
    
}
```
... kommt die Meldung: _java.lang.AssertionError: expected:<n. a.> but was:<null>_

Irgendwas passt da wohl mit dem Konstruktor nicht?!


----------



## Supeq (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Ich frag mich grad warum du die Methoden nicht Static machst, dann kannst du dir das ganze manuelle Instanzieren sparen und für spätere Anwendungen der Klasse ist es auch einfacher. Hier mal meine Version der convertToDecimal:


```
// *Konstruktoren und Klassen-Variablen rausgeschmissen *


    public static int convertToDecimal(String romanNum) {  
        char lastChar=' ';
        int decimalNum = 0;
                
        for (int i=romanNum.length(); i>=1; i--) { // begin at the right end of the string (= Roman number)
            switch (romanNum.toUpperCase().charAt(i-1)) { // check the char on each position
                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimalNum-=1;
                    } else {
                        decimalNum+=1;
                    }
                    break;
                case 'V':
                    decimalNum+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimalNum-=10;
                    } else {
                        decimalNum+=10;
                    }
                    break;
                case 'L':
                    decimalNum+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimalNum-=100;
                    } else {
                        decimalNum+=100;
                    }
                    break;
                case 'D':
                    decimalNum+=500;
                    break;
                case 'M':
                    decimalNum+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i-1); // after each round, make current index of the string to position of last char
            }

            
        return decimalNum;    
    }
```

Läuft ^^

Deine doppelten Werte kommen übrigens daher, das du die Methode convertToRoman() zweimal aufrufst und zwar im Konstruktor und dann nochmal explizit (wobei die "decimalNum" zwischendurch *nicht *resetted wird)


----------



## boss3D (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Moment mal ... habe gerade was rausgefunden: Selbst wenn ich meinen Code lasse (ohne deine Änderungen) kommt schon das richtige raus, wenn ich nur _int decimalNum = 0; _am Beginn der Methode einfüge!

Scheinbar stimmt meine Logik doch, nur initialisiert Java Variablen wohl nicht standardmäßig mit 0, wie ich ursprünglich dachte?! Wenn decimanlNum bereits irgendeinen Initialwert != 0 hat, ist klar, dass das dann mit den ganzen += und -= nie auf den richtigen Wert rauslaufen kann.

Ich hätte mir allerdings gedacht, dass die decimanlNum-*Konstanten* verwendet werden würde. Jetzt wird ein gleichnamiger int verwendet. Irgendwie habe ich hier das Gefühl, zu viele Sachen anzulegen?! Jetzt sind ja bald die Konstruktoren/Konstanten umsonst?! 
BTW: Wenn ich die Methoden _static_ mache, dann kommt beim Aufruf in den Konstruktoren: _The static method convertToDecimal() from the type RomanNumber should be accessed in a static way
_Und bei den Aufrufen der Konstanten kommt:_ Cannot make a static reference to the non-static field romanNum. Change modifier of 'romanNum' to static.

_^^ Drum sag ich ja, ich mag_ static _überhaupt nicht. Da kommen nur immer irgendwelche Probleme. Zumindest, wenn man noch nicht richtig weiß/versteht, wie das in der gesamten Klasse anzuwenden ist ..._ 
_


----------



## Supeq (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Hab meinen vorigen Beitrag nochmal editiert, da steht warum es zu doppelten Werten kam^^


----------



## boss3D (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Ja, aber macht das dann nicht wirklich die Konstruktoren überflüssig? BTW meinst du mit dem zweiten expliziten Aufruf den in der TestKlasse, oder?


----------



## Supeq (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Diesen "assertEquals("n. a.", *roman.convertToRoman(*));" Aufruf meinte ich damit.

Wenn du nur statische Mehtoden in deiner Klasse verwendest dann ist ein Konstruktor überflüssig, weil du ja die Methoden aufrufen kannst ohne vorher ein Objekt zu instanzieren. Das ist ja grad das, was statische Mehtoden ausmachen. Schau dir mal die Java-Basicklassen , bspw. Math (Math (Java Platform SE 6)) an, dort sind auch alle Methoden statisch.


----------



## boss3D (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Ok ... ich habe aber stark den Verdacht, dass die Aufgabe mit Konstruktoren gelöst werden sollte, wie auch DarkMo das angenommen hat. Insofern spare ich mir lieber das _static_. 

Mir kommt nur immer noch das hier irgendwie "sinnlos" vor: _int decimalNum=0;_ ???
decimalNum gäb's ja schon als Konstante. Das jetzt trotzdem noch mal als int anlegen?! Kann man das nicht "eleganter" lösen, dass es trotzdem mit 0 initialisiert bleibt und ich keine doppelten Werte bekomme?
Und bei der convertToRoman Methode habe ich das Problem, dass die TestKlasse meint:
_ java.lang.NullPointerException
 at RomanNumber.convertToDecimal(RomanNumber.java:48)
 at RomanNumberTest.testConvertToRoman(RomanNumberTest.java:17)_


----------



## Supeq (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Also in deiner Aufgabenstellung steht nix davon, das man Konstruktoren verwenden muss. Aber okay , geht ja auch ohne static^^

Mir fällt jetzt spontan keine elegantere Lösung als Static-Methoden ein um deine Zählvariable (decimalNum) zurückzusetzen. 

Unelegant finde ich es aber auch nicht, die Variable "per Hand" wieder auf 0 zu setzen. An irgendeiner Stelle musst du das ja definieren, woher soll dein Programm sonst wissen das die Variable nicht noch weiter verwendet wird. 
Du könntest natürlich den Aufruf der Methode im Konstruktor entfernen(da hat die eigtl. sowieso nix zu suchen), aber ich dreh mich hier im Kreis weil static-Methoden die logische und offensichtliche Lösung für derartige Probleme sind.



boss3D schrieb:


> decimalNum gäb's ja schon als Konstante.



Was meinst du mit Konstante? Das is doch ne Variable


----------



## boss3D (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Ich bin gerade stark am Überlegen, ob's nicht am schlauesten/elegantesten wäre, noch wenigstens eine getRoman() Methode zu machen, so wie DarkMo das auch schon vorgeschlagen hat. Vielleicht muss ich mir dann nicht so viele Gedanken um (Doppel)Initialisierungen machen?! Mal schauen, worauf ich da noch komme ...

*[EDIT]*
Alle Fehler beseitigt! 
So funktioniert jetzt erst mal alles (zumindest gültige Umwandlungen):

```
public class RomanNumber {
    
    private String romanNum;
    private int decimalNum;
    
    [COLOR=royalblue]/**
     * Constructor
     * used if there's no display of a Roman number
     * or it's decimal value is 0
     */    RomanNumber() {
        this.romanNum = "n. a.";
        this.decimalNum = 0;
    }
    
    [COLOR=royalblue]/**
     * Constructor
     * used for the decimal representation of a Roman number
     * @param rNum is any Roman number
     */    RomanNumber(String rNum) {
        this.romanNum = rNum;
        this.convertToDecimal();
    }
    
    [COLOR=royalblue]/**
     * Constructor
     * used for the Roman representation of a decimal integer
     * @param dNum is any integer number
     */    RomanNumber(int dNum) {
        this.decimalNum = dNum;
        this.convertToRoman();
    }
        
   [COLOR=royalblue] /**
     * @return calculated decimal value of a specific Roman number
     */    public int convertToDecimal() {  
        char lastChar=' ';
        int decimalNum=0;
                
        for (int i=romanNum.length()-1; i>=0; i--) { [COLOR=seagreen]// begin at the right end of the string (= Roman number)            switch (romanNum.toUpperCase().charAt(i)) { [COLOR=seagreen]// check the char on each position                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimalNum-=1;
                    } else {
                        decimalNum+=1;
                    }
                    break;
                case 'V':
                    decimalNum+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimalNum-=10;
                    } else {
                        decimalNum+=10;
                    }
                    break;
                case 'L':
                    decimalNum+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimalNum-=100;
                    } else {
                        decimalNum+=100;
                    }
                    break;
                case 'D':
                    decimalNum+=500;
                    break;
                case 'M':
                    decimalNum+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i); [COLOR=seagreen]// after each round, make current index of the string to position of last char            }

            
        return decimalNum;    
    }
    
    [COLOR=royalblue]/**
     * @return calculated Roman number of a decimal integer
     */    public String convertToRoman() {        
        String roman="";
        int value=decimalNum;
        
        if (value==0) {
            return romanNum; [COLOR=seagreen]// in this case "n. a."        }

        if (value>=0) {
            while (value/1000 >= 1) { [COLOR=seagreen]// while division by 1000 is possible, do so                roman+="M";
                value-=1000;
            }
            if (value/900 >= 1) { [COLOR=seagreen]// if division by 1000 is no longer possible, continue with the next smaller integer                roman+="CM";
                value-=900;
            }
            if (value/500 >= 1) {
                roman+="D";
                value = value - 500;
            } 
            if (value/400 >= 1) {
                roman+="CD";
                value-=400;
            }
            while (value/100 >= 1) { [COLOR=seagreen]// while division by 100 is possible, do so                roman+="C";
                value-=100;
            }
            if (value/90 >= 1) { [COLOR=seagreen]// if division by 100 is no longer possible, continue with the next smaller integer                roman+="XC";
                value-=90;
            }
            if (value/50 >= 1) {
                roman+="L";
                value-=50;
            }
            if (value/40 >= 1) {
                roman+="XL";
                value-=40;
            }
            while (value/10 >= 1) { [COLOR=seagreen]// while division by 10 is possible, do so                roman+="X";
                value-=10;
            }
            if (value/9 >= 1) { [COLOR=seagreen]// if division by 10 is no longer possible, continue with the next smaller integer                roman+="IX";
                value-=9;
            }
            if (value/5 >= 1) {
                roman+="V";
                value-=5;
            }
            if (value/4 >= 1) {
                roman+="IV";
                value-=4;
            }
            while (value >= 1) {
                roman+="I";
                value-=1;
            }
        }
        
        return roman;
    }

}
```


```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class RomanNumberTest {
    
    @Test
    public void testConvertToDecimal() {
        RomanNumber roman = new RomanNumber("MCDXXVI");
        assertEquals(1426, roman.convertToDecimal());
    }
    
    @Test
    public void testConvertToRoman() {
        RomanNumber roman = new RomanNumber(1426);
        assertEquals("MCDXXVI", roman.convertToRoman());
    }
    
}
```
Nur sowas hier geht noch nicht. Das muss ich noch ändern:
_java.lang.AssertionError: expected:<n. a.> but was:<null>_

```
@Test
    public void testConvertToRoman() {
        RomanNumber roman = new RomanNumber(0);
        assertEquals("n. a.", roman.convertToRoman());
    }
```
^^ Nur wie?

Muss ich da irgendwie der entsprechenden Methode sagen, dass sie in dem Fall auf den ersten Konrtuktor zugreifen soll?! Definiert hätten wir den Fall darin ja schon ...


----------



## Supeq (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Der erste Konstruktor wird nur aufgerufen wenn du nichts übergibst  Das steht in deinem Kommentar auch falsch ^^( "or it's decimal value is 0")

Ich würd den ersten Konstruktor löschen und dafür in der converToRoman folgendes ändern:


```
if (value==0) {
            return romanNum; // in this case "n. a."
        }
```

zu


```
if (value==0) {
            return "n. a."; // in this case "n. a."
        }
```

Dann hast du´s^^


----------



## boss3D (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Ja, das ist schon klar, dass der nur dann aufgerufen wird, aber ich übergebe ja eh nichts, oder? Wo denn?

Wie man's sonst lösen könnte, weiß ich, aber ich hätte es halt gerne über den/die Konstruktor(en) gelöst. Wozu habe ich die denn sonst gemacht? Ich hoffe, DarkMo sagt dazu nochmal was. War ja seine Idee und mich würd's rein vom Verständnis her interessieren. 

BTW: Ich glaube, so, wie's mein Kommentar sagt, wäre der Konstruktor gedacht?! Nur "verwende" ich den dann nicht/falsch?!


----------



## Supeq (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

RomanNumber roman = new RomanNumber(0);

Da übergibst du doch die 0^^  Deswegen wird Konstruktor eins nicht aufgerufen.

So wie im Kommentar gedacht kannst du den Konstruktor nicht aufrufen weil du versuchst zwei unterschiedliche Situationen in einen Konstruktor zu packen (kein Parameter / Parameter =0).


----------



## boss3D (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Oha! Ich habe gedacht dieses "RomanNumber" wäre die Klasse, die ich aufrufe, aber ist natürlich Blödsinn! Hätte der Hausverstand sagen können, dass es sich dabei um ein neues Objekt der (gleichnamigen) Klasse handelt, das eben vom Konstruktor erzeugt wird._ *shame on me*_ 

Dann stellt sich aber die Frage, wie ich explizit angeben kann, dass sich das "römische" "n. a." auf einen dezimalen 0er bezieht. Bzw. auf irgendeinen anderen ungültigen dezimalen Wert, wie z.B. negative Zahlen. ???

*[EDIT]*
Ok, so geht's scheinbar:

```
@Test
    public void testConvertToRomanInvalid() {
        RomanNumber roman = new RomanNumber();
        roman.decimalNum = 0;
        assertEquals("n. a.", roman.convertToRoman());
    }
```
Aber dann muss das _private_ in der RomanNumber Klasse vor den Konstanten weg. Ist eh kein Problem, oder?

So ganz langsam blicke ich bei den Konstruktoren durch. Der nächste Schritt ist jetzt, es zu schaffen, dass negative integer genauso zu "n. a." führen ...
Aber ich kann mir ja nicht in den Konstruktor ifs reinbasteln?!


----------



## Supeq (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Ich will dich nicht verwirren, deswegen bleib ich jetzt mal bei deinem Programmierstil 

Du musst dir bewusst machen, das es zwei Fälle sind die du versuchst abzudecken. Den ersten Fall würde ich so handeln:


```
// Konstruktor "Kein Parameter"   
        RomanNumber() {
        return "n. a.";  // alles andere wäre überflüssig
    }
```

Und wenn ein Wert kleiner eins eingegeben wird, muss die convertToRoman-Methode sich darum kümmern. Dazu könntest du zu Beginn der Methode ein "if(dNum<1){return "n.a.";}" einfügen.


----------



## boss3D (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

So geht's auch:

```
if (value<=1) {
            decimalNum=0;
            return romanNum; // in this case "n. a."
        }
```


```
@Test
    public void testConvertToRomanInvalid() {
        RomanNumber roman = new RomanNumber();
        roman.decimalNum = -1;
        assertEquals("n. a.", roman.convertToRoman());
        assertEquals(0, roman.decimalNum);
    }
```
Ich probiere jetzt mal die "normalisierte Form". Ich habe da schon eine Idee und witzigerweise erkennt die convertToDecimal Methode immer den richtigen dezimalen int, selbst wenn ein "römischer Blödsinn" eingegeben wird. Da muss ich gar nicht selbst herumraten. Vielleicht lässt sich das schon irgendwie ausnutzen. 

*[EDIT]*
Könnte man "geschummelt" nennen, geht aber so:

```
@Test
    public void testNormalizedForm() {
        RomanNumber roman = new RomanNumber("IXX");
        assertEquals(19, roman.convertToDecimal());
        roman.decimalNum = roman.convertToDecimal();
        assertEquals("XIX", roman.convertToRoman());
    }
```


----------



## boss3D (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

*[EDIT]*
Jetzt stimmt's auch mit den Sonderzeichen:

```
[COLOR=royalblue]/**
     * @return calculated decimal value of a specific Roman number
     */    public int convertToDecimal() {  
        char lastChar=' ';
        int decimalNum=0;
        int i=0;
        
        [COLOR=seagreen]// Check for invalid symbols in the Roman number string        [B]while (i<romanNum.length()) {
            if (romanNum.toUpperCase().charAt(i)!='I' && 
                romanNum.toUpperCase().charAt(i)!='V' &&
                romanNum.toUpperCase().charAt(i)!='X' && 
                romanNum.toUpperCase().charAt(i)!='L' && 
                romanNum.toUpperCase().charAt(i)!='C' && 
                romanNum.toUpperCase().charAt(i)!='D' && 
                romanNum.toUpperCase().charAt(i)!='M') {
                return decimalNum;
            }
            i++;
        }
        i=0;[/B]
                      
        for (i=romanNum.length()-1; i>=0; i--) { [COLOR=seagreen]// begin at the right end of the string (= Roman number)            switch (romanNum.toUpperCase().charAt(i)) {[COLOR=seagreen] // check the char on each position                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimalNum-=1;
                    } else {
                        decimalNum+=1;
                    }
                    break;
                case 'V':
                    decimalNum+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimalNum-=10;
                    } else {
                        decimalNum+=10;
                    }
                    break;
                case 'L':
                    decimalNum+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimalNum-=100;
                    } else {
                        decimalNum+=100;
                    }
                    break;
                case 'D':
                    decimalNum+=500;
                    break;
                case 'M':
                    decimalNum+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i); [COLOR=seagreen]// after each round, make current index of the string to position of last char            }

            
        return decimalNum;    
    }
```
Damit habe ich eh bald alles abgedeckt, was die Aufgabe haben will, oder liest da noch jemand was raus, das mir fehlt?

*[EDIT2]*
Ok, das fehlt noch:


> Wie mit unsinnigen Kombinationen (z. B. LDDCCMD) umgegangen werden soll, soll von euch festgelegt werden (Dokumentation nicht vergessen!).


----------



## DarkMo (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

sry war auf arbeit ^^

also in konstruktoren kannst du natürlich auch if's usw verwenden, kein thema. joa, das mit den konstruktoren hat sich ja soweit geklärt... der default konstruktor wäre dann eben ...new RomanNumber(); aber das haste ja auch schon erkannt ^^ hmm, irgendwie bin ich grad matschig in der birne xD


----------



## boss3D (15. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ No Probs ... 

Ich muss mir nur noch was sinnvolles überlegen, was mit unsinnigen Kombinatione (siehe oben EDIT2) passieren soll. Wenn da wer Ideen hätte, wäre es gut.
Alles andere aus der Aufgabenstellung müsste durch meinen derzeitigen Code bereits abgedeckt sein?! Was nur sein kann, ist, dass ich doch noch eine main reinbasteln muss, die dann Ausgaben von röm --> int und int --> röm macht. Habe diesbezüglich ein mail an die Lehrerin (soviel zu "was *er* da will" _*lol*_) geschrieben.


Spoiler





```
public class RomanNumber {
    
    String romanNum;
    int decimalNum;
    
   [COLOR=royalblue] /**
     * Constructor
     * used if there's no (valid) representation of a Roman number
     * or it's decimal value is <=0
     */    RomanNumber() {
        this.romanNum = "n. a.";
    }
    
    [COLOR=royalblue]/**
     * Constructor
     * used for the decimal representation of a Roman number
     * @param rNum is any Roman number
     */    RomanNumber(String rNum) {
        this.romanNum = rNum;
        this.convertToDecimal();
    }
    
   [COLOR=royalblue] /**
     * Constructor
     * used for the Roman representation of a decimal integer
     * @param dNum is any integer number
     */    RomanNumber(int dNum) {
        this.decimalNum = dNum;
        this.convertToRoman();
    }
        
   [COLOR=royalblue] /**
     * @return calculated decimal value of a specific Roman number
     */    public int convertToDecimal() {  
        char lastChar=' ';
        int decimal=0;
        int i=0;
        
       [COLOR=seagreen] // Check for invalid symbols in the Roman number string        while (i<romanNum.length()) {
            if (romanNum.toUpperCase().charAt(i)!='I' && 
                romanNum.toUpperCase().charAt(i)!='V' && 
                romanNum.toUpperCase().charAt(i)!='X' && 
                romanNum.toUpperCase().charAt(i)!='L' &&
                romanNum.toUpperCase().charAt(i)!='C' && 
                romanNum.toUpperCase().charAt(i)!='D' && 
                romanNum.toUpperCase().charAt(i)!='M') {
                return decimal;
            }
            i++;
        }
                      
        for (i=romanNum.length()-1; i>=0; i--) { [COLOR=seagreen]// begin at the right end of the string (= Roman number)            switch (romanNum.toUpperCase().charAt(i)) { [COLOR=seagreen]// check the char on each position                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimal-=1;
                    } else {
                        decimal+=1;
                    }
                    break;
                case 'V':
                    decimal+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimal-=10;
                    } else {
                        decimal+=10;
                    }
                    break;
                case 'L':
                    decimal+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimal-=100;
                    } else {
                        decimal+=100;
                    }
                    break;
                case 'D':
                    decimal+=500;
                    break;
                case 'M':
                    decimal+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i);[COLOR=seagreen] // after each round, make current index of the string to position of last char            }
           
        return decimal;    
    }
    
    [COLOR=royalblue]/**
     * @return calculated Roman number of a decimal integer
     */    public String convertToRoman() {        
        String roman="";
        int value=decimalNum;
       
        if (value<=1) {
            decimalNum=0;
            return romanNum; [COLOR=seagreen]// in this case "n. a."        }

        if (value>=0) {
            while (value/1000 >= 1) { [COLOR=seagreen]// while division by 1000 is possible, do so                roman+="M";
                value-=1000;
            }
            if (value/900 >= 1) { [COLOR=seagreen]// if division by 1000 is no longer possible, continue with the next smaller integer                roman+="CM";
                value-=900;
            }
            if (value/500 >= 1) {
                roman+="D";
                value = value - 500;
            } 
            if (value/400 >= 1) {
                roman+="CD";
                value-=400;
            }
            while (value/100 >= 1) { [COLOR=seagreen]// while division by 100 is possible, do so                roman+="C";
                value-=100;
            }
            if (value/90 >= 1) { [COLOR=seagreen]// if division by 100 is no longer possible, continue with the next smaller integer                roman+="XC";
                value-=90;
            }
            if (value/50 >= 1) {
                roman+="L";
                value-=50;
            }
            if (value/40 >= 1) {
                roman+="XL";
                value-=40;
            }
            while (value/10 >= 1) { [COLOR=seagreen]// while division by 10 is possible, do so                roman+="X";
                value-=10;
            }
            if (value/9 >= 1) { [COLOR=seagreen]// if division by 10 is no longer possible, continue with the next smaller integer                roman+="IX";
                value-=9;
            }
            if (value/5 >= 1) {
                roman+="V";
                value-=5;
            }
            if (value/4 >= 1) {
                roman+="IV";
                value-=4;
            }
            while (value >= 1) {
                roman+="I";
                value-=1;
            }
        }
        
        return roman;
    }

}
```



Vorerst mache ich jetzt mal beim zweiten Bsp. (nicht auf der Angabe in Posting #1 zu sehen) weiter. Wenn da fragen kommen, poste ich die ebenfalls ...

Danke schon mal soweit!
------------

*[EDIT]*
Jetzt zu Bsp 2:




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



^^ Also, es geht darum, dass ich einen fehlerhaften/unvollständigen Code zu einer Wetterstation bekommen habe und den gemäß der Angabe korrigieren/erweitern soll. 

Hier der fehlerhafte/unvollständige Code:


Spoiler





```
public class weather_station {

    static final int NUMBER_OF_READINGS = 3;
    static final int MAX_NUMBER_OF_STATIONS = 5;

    static weather_station[] stations = new weather_station[MAX_NUMBER_OF_STATIONS];
    static int stationCounter = 0;

    static float overallMinTemperature;
    static String overallMinTemperatureLocation;
    
    static float overallMaxTemperature;
    static String overallMaxTemperatureLocation;
    
    static float maxTotalRainfall;
    static String maxTotalRainfallLocation;

    final String location;

    float minTemperature, maxTemperature;

    float totalRainfall = 0;

    reading[] readings = new reading[NUMBER_OF_READINGS];
    int indexOfNextReading = 0;
    int indexOfLastReading;

    public weather_station(String location) {
        this.location = location;
        while (stationCounter < MAX_NUMBER_OF_STATIONS) {
            stations[stationCounter++] = this;
        }
    }

    void addReading(reading r) {
        readings[indexOfNextReading] = r;
        updateStatistics(r);
        indexOfLastReading = indexOfNextReading;
        indexOfNextReading = ++indexOfNextReading % 3;
    }

    void updateStatistics(reading r) {
        updateMinTemperature(r);
        updateMaxTemparature(r);
        updateRainfall(r);
        UpdateOverallRainfallStatistics(totalRainfall, location);
        UpdateOverallStatistics(r, location);
    }

    void updateRainfall(reading r) {
        totalRainfall += r.rainfall;
    }

    void updateMaxTemparature(reading r) {
        if (r.temperature > maxTemperature) {
            maxTemperature = r.temperature;
        }
    }

    void updateMinTemperature(reading r) {
        if (r.temperature < minTemperature) {
            minTemperature = r.temperature;
        }
    }

    void showMinTemperature() {
        System.out.println("Lowest Temperature: " + minTemperature + " Degree Celsius");
    }

    void showMaxTemperature() {
        System.out.println("Highest Temperature: " + maxTemperature + " Degree Celsius");
    }

    void showLatestReadings() {
        System.out.println("Latest Readings for " + location);
        for (int i = 0; i < readings.length; i++) {
            if (readings[i] != null) {
            System.out.println(readings[i].toString());
            }
        }
    }
    
    void reset() {
        readings = new reading[NUMBER_OF_READINGS];
        minTemperature = 0;
        maxTemperature = 0;
        totalRainfall = 0;
    }

    static void UpdateOverallStatistics(reading r, String location) {
        if (r.temperature < overallMinTemperature) {
            overallMinTemperature = r.temperature;
            overallMinTemperatureLocation = location;
        }
        if (r.temperature > overallMinTemperature) {
            overallMaxTemperature = r.temperature;
            overallMaxTemperatureLocation = location;
        }
    }

    static void UpdateOverallRainfallStatistics(float totalRainfall, String location) {
        if (totalRainfall > maxTotalRainfall) {
            maxTotalRainfall = totalRainfall;
            maxTotalRainfallLocation = location;
        }
    }

    static void showOverallMinTemperature() {
        System.out.println("Lowest Temperature: " + overallMinTemperature + " Degree Celsius in " + overallMinTemperatureLocation);
    }

    static void showOverallMaxTemperature() {
        System.out.println("Highest Temperature: " + overallMaxTemperature + " Degree Celsius in " + overallMaxTemperatureLocation);
    }

    static void showMaxTotalRainfall() {
        System.out.println("Max Amount of Rainfall: " + maxTotalRainfall + " ml in " + maxTotalRainfallLocation);
    }

    static void resetStations() {
        overallMaxTemperature = 0;
        overallMinTemperature = 0;
        maxTotalRainfall = 0;
        for (int i = 0; i < stationCounter; i++) {
            stations[i].reset();
        }
    }

}
```






Spoiler





```
import static org.junit.Assert.assertEquals;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class weather_station_test {

    weather_station linz;
    weather_station wels;
    weather_station hagenberg;
    weather_station steyr;

    @Before
    public void setUp() throws Exception {
        linz = new weather_station("Linz");
        wels = new weather_station("Wels");
        hagenberg = new weather_station("Hagenberg");
        steyr = new weather_station("Steyr");

        linz.addReading(new reading(14, 0));
        linz.addReading(new reading(16, 34));

        wels.addReading(new reading(10, 2));
        wels.addReading(new reading(-8, 3));

        hagenberg.addReading(new reading(-20, 0));
        hagenberg.addReading(new reading(0, 0));

        steyr.addReading(new reading(23, 23));
        steyr.addReading(new reading(21, 3213));
    }

    @After
    public void tearDown() throws Exception {
        weather_station.resetStations();
    }

    @Test
    public void testLinz() {
        assertEquals(14, linz.minTemperature, 0.000001);
        assertEquals(16, linz.maxTemperature, 0.000001);
        assertEquals(34, linz.totalRainfall, 0.000001);
    }

    @Test
    public void testWels() {
        assertEquals(-8, wels.minTemperature, 0.000001);
        assertEquals(10, wels.maxTemperature, 0.000001);
        assertEquals(5, wels.totalRainfall, 0.000001);
    }

    @Test
    public void testHagenberg() {
        assertEquals(-20, hagenberg.minTemperature, 0.000001);
        assertEquals(0, hagenberg.maxTemperature, 0.000001);
        assertEquals(0, hagenberg.totalRainfall, 0.000001);
    }

    @Test
    public void testSteyr() {
        assertEquals(21, steyr.minTemperature, 0.000001);
        assertEquals(23, steyr.maxTemperature, 0.000001);
        assertEquals(3213, steyr.totalRainfall, 0.000001);
    }

    @Test
    public void testStatistics() {
        assertEquals(-20, weather_station.overallMinTemperature, 0.000001);
        assertEquals("Hagenberg", weather_station.overallMinTemperatureLocation);
        assertEquals(23, weather_station.overallMaxTemperature, 0.000001);
        assertEquals("Styer", weather_station.overallMaxTemperatureLocation);
        assertEquals(3213, weather_station.maxTotalRainfall, 0.000001);
        assertEquals("Steyr", weather_station.maxTotalRainfallLocation);
    }
}
```






Spoiler





```
public class reading {
    float temperature;
    float rainfall;

    public reading(float temperature, float rainfall) {
        this.temperature = temperature;
        this.rainfall = rainfall;
    }

    @Override
    public String toString() {
        return temperature + " Degree Celsius, rainfall: " + rainfall + " mm";
    }

}
```



Und hier die Codes, soweit ich sie schon korrigiert/erweitert habe


Spoiler





```
public class weather_station {

    static final int DEFAULT_MAXIMUM_TEMPERATURE = -273;
    static final int DEFAULT_MINIMUM_TEMPERATURE = 100;
    static final int NUMBER_OF_READINGS = 3;
    static final int MAX_NUMBER_OF_STATIONS = 5;

    static weather_station[] stations = new weather_station[MAX_NUMBER_OF_STATIONS];
    static int stationCounter = 0;

    static float overallMinTemperature;
    static String overallMinTemperatureLocation;

    static float overallMaxTemperature;
    static String overallMaxTemperatureLocation;

    static float maxTotalRainfall;
    static String maxTotalRainfallLocation;

    final String location;

    float minTemperature = DEFAULT_MINIMUM_TEMPERATURE;
    float maxTemperature = DEFAULT_MAXIMUM_TEMPERATURE;

    float totalRainfall = 0;

    reading[] readings = new reading[NUMBER_OF_READINGS];
    int indexOfNextReading = 0;
    int indexOfLastReading;

    public weather_station(String location) {
        this.location = location;
        while (stationCounter < MAX_NUMBER_OF_STATIONS) {
            stations[stationCounter++] = this;
        }
    }

    void addReading(reading r) {
        readings[indexOfNextReading] = r;
        updateStatistics(r);
        indexOfLastReading = indexOfNextReading;
        indexOfNextReading = ++indexOfNextReading % 3;
    }

    void updateStatistics(reading r) {
        updateMinTemperature(r);
        updateMaxTemparature(r);
        updateRainfall(r);
        UpdateOverallRainfallStatistics(this.totalRainfall, this.location);
        UpdateOverallStatistics(r, this.location);
    }

    void updateRainfall(reading r) {
        totalRainfall += r.rainfall;
    }

    void updateMaxTemparature(reading r) {
        if (r.temperature > maxTemperature) {
            this.maxTemperature = r.temperature;
        }
    }

    void updateMinTemperature(reading r) {
        if (r.temperature < minTemperature) {
            this.minTemperature = r.temperature;
        }
    }

    void showMinTemperature() {
        System.out.println("Lowest Temperature: " + minTemperature + " Degree Celsius");
    }

    void showMaxTemperature() {
        System.out.println("Highest Temperature: " + maxTemperature + " Degree Celsius");
    }

    void showLatestReadings() {
        System.out.println("Latest Readings for " + this.location);
        for (int i = 0; i < readings.length; i++) {
            if (readings[i] != null) {
                System.out.println(readings[i].toString());
            }
        }
    }

    void reset() {
        readings = new reading[NUMBER_OF_READINGS];
        minTemperature = 100;
        maxTemperature = DEFAULT_MAXIMUM_TEMPERATURE;
        totalRainfall = 0;
    }

    static void UpdateOverallStatistics(reading r, String location) {
        if (r.temperature < overallMinTemperature) {
            overallMinTemperature = r.temperature;
            overallMinTemperatureLocation = location;
        }
        if (r.temperature > overallMaxTemperature) {
            overallMaxTemperature = r.temperature;
            overallMaxTemperatureLocation = location;
        }
    }

    static void UpdateOverallRainfallStatistics(float totalRainfall, String location) {
        if (totalRainfall > maxTotalRainfall) {
            maxTotalRainfall = totalRainfall;
            maxTotalRainfallLocation = location;
        }
    }

    static void showOverallMinTemperature() {
        System.out.println("Lowest Temperature: " + overallMinTemperature + " Degree Celsius in " + overallMinTemperatureLocation);
    }

    static void showOverallMaxTemperature() {
        System.out.println("Highest Temperature: " + overallMaxTemperature + " Degree Celsius in " + overallMaxTemperatureLocation);
    }

    static void showMaxTotalRainfall() {
        System.out.println("Max Amount of Rainfall: " + maxTotalRainfall + " ml in " + maxTotalRainfallLocation);
    }

    static void resetStations() {
        overallMaxTemperature = DEFAULT_MAXIMUM_TEMPERATURE;
        overallMinTemperature = null;
        maxTotalRainfall = DEFAULT_MINIMUM_TEMPERATURE;
        overallMinTemperatureLocation = null;
        maxTotalRainfall = 0;
        maxTotalRainfallLocation = null;
        for (int i = 0; i < stationCounter; i++) {
            stations[i].reset();
        }
    }

}
```






Spoiler





```
import static org.junit.Assert.assertEquals;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class weather_station_test {

    weather_station linz = new weather_station("Linz");
    weather_station wels = new weather_station("Wels");
    weather_station hagenberg = new weather_station("Hagenberg");
    weather_station steyr = new weather_station("Steyr");

    @Before
    public void setUp() throws Exception {
        linz = new weather_station("Linz");
        wels = new weather_station("Wels");
        hagenberg = new weather_station("Hagenberg");
        steyr = new weather_station("Steyr");
    
        linz.addReading(new reading(14, 0));
        linz.addReading(new reading(16, 34));
        
        linz.showLatestReadings();
        linz.showMaxTemperature();
        linz.showMinTemperature();
    
        wels.addReading(new reading(10, 2));
        wels.addReading(new reading(-8, 3));
        
        wels.showLatestReadings();
        wels.showMaxTemperature();
        wels.showMinTemperature();
    
        hagenberg.addReading(new reading(-20, 0));
        hagenberg.addReading(new reading(0, 0));
        
        hagenberg.showLatestReadings();
        hagenberg.showMaxTemperature();
        hagenberg.showMinTemperature();
    
        steyr.addReading(new reading(23, 23));
        steyr.addReading(new reading(21, 3213));
        
        steyr.showLatestReadings();
        steyr.showMaxTemperature();
        steyr.showMinTemperature();
        
        WeatherStation.showOverallMinTemperature();
        WeatherStation.showOverallMaxTemperature();
        WeatherStation.showMaxTotalRainfall();
        
        WeatherStation.resetStations();
        WeatherStation.showOverallMinTemperature();
        WeatherStation.showOverallMaxTemperature();
        WeatherStation.showMaxTotalRainfall();
    }

    @After
    public void tearDown() throws Exception {
        weather_station.resetStations();
    }

    @Test
    public void testLinz() {
        assertEquals(14, linz.minTemperature, 0.000001);
        assertEquals(16, linz.maxTemperature, 0.000001);
        assertEquals(34, linz.totalRainfall, 0.000001);
    }

    @Test
    public void testWels() {
        assertEquals(-8, wels.minTemperature, 0.000001);
        assertEquals(10, wels.maxTemperature, 0.000001);
        assertEquals(5, wels.totalRainfall, 0.000001);
    }

    @Test
    public void testHagenberg() {
        assertEquals(-20, hagenberg.minTemperature, 0.000001);
        assertEquals(0, hagenberg.maxTemperature, 0.000001);
        assertEquals(0, hagenberg.totalRainfall, 0.000001);
    }

    @Test
    public void testSteyr() {
        assertEquals(21, steyr.minTemperature, 0.000001);
        assertEquals(23, steyr.maxTemperature, 0.000001);
        assertEquals(3213, steyr.totalRainfall, 0.000001);
    }

    @Test
    public void testStatistics() {
        assertEquals(-20, weather_station.overallMinTemperature, 0.000001);
        assertEquals("Hagenberg", weather_station.overallMinTemperatureLocation);
        assertEquals(23, weather_station.overallMaxTemperature, 0.000001);
        assertEquals("Styer", weather_station.overallMaxTemperatureLocation);
        assertEquals(3213, weather_station.maxTotalRainfall, 0.000001);
        assertEquals("Steyr", weather_station.maxTotalRainfallLocation);
    }
}
```






Spoiler





```
public class reading {
    float temperature; 
    float rainfall; 
    
    public reading(float temperature, float rainfall) {
        this.temperature = temperature;
        this.rainfall = rainfall;
    }

    @Override
    public String toString() {
        return temperature + " Degree Celsius, rainfall: " + rainfall + " mm";
    }

}
```



^^ Eigentlich scheitert's eh nur noch an der Korrektur der TestKlasse. Alles andere müsste schon soweit passen?! 

Am besten/leichtesten wäre es, wenn sich jemand die Codes ins Eclipse kopieren könnte, damit man auch die Fehlermeldungen angezeigt bekommt. So wird's wahrscheinlich schwierig, diese zu sehen ...


----------



## boss3D (16. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

So, habe jetzt auch im 2er Bsp nahezu alle Fehler ausbessern können. Die Codes sehen jetzt so aus:


Spoiler





```
public class weather_station {

    static final int DEFAULT_MAXIMUM_TEMPERATURE = -273;
    static final int DEFAULT_MINIMUM_TEMPERATURE = 100;
    static final int NUMBER_OF_READINGS = 3;
    static final int MAX_NUMBER_OF_STATIONS = 5;

    static weather_station[] stations = new weather_station[MAX_NUMBER_OF_STATIONS];
    static int stationCounter = 0;

    static float overallMinTemperature;
    static String overallMinTemperatureLocation;
    
    static float overallMaxTemperature;
    static String overallMaxTemperatureLocation;
    
    static float maxTotalRainfall;
    static String maxTotalRainfallLocation;

    final String location;

    float minTemperature = DEFAULT_MINIMUM_TEMPERATURE;
    float maxTemperature = DEFAULT_MAXIMUM_TEMPERATURE;

    float totalRainfall = 0;

    reading[] readings = new reading[NUMBER_OF_READINGS];
    int indexOfNextReading = 0;
    int indexOfLastReading;

    public weather_station(String location) {
        this.location = location;
        while (stationCounter < MAX_NUMBER_OF_STATIONS) {
            stations[stationCounter++] = this;
        }
    }

    void addReading(reading r) {
        readings[indexOfNextReading] = r;
        updateStatistics(r);
        indexOfLastReading = indexOfNextReading;
        indexOfNextReading = ++indexOfNextReading % 3;
    }

    void updateStatistics(reading r) {
        updateMinTemperature(r);
        updateMaxTemparature(r);
        updateRainfall(r);
        UpdateOverallRainfallStatistics(this.totalRainfall, this.location);
        UpdateOverallStatistics(r, this.location);
    }

    void updateRainfall(reading r) {
        totalRainfall += r.rainfall;
    }

    void updateMaxTemparature(reading r) {
        if (r.temperature > maxTemperature) {
            this.maxTemperature = r.temperature;
        }
    }

    void updateMinTemperature(reading r) {
        if (r.temperature < minTemperature) {
            this.minTemperature = r.temperature;
        }
    }

    void showMinTemperature() {
        System.out.println("Lowest Temperature: " + minTemperature + " Degree Celsius");
    }

    void showMaxTemperature() {
        System.out.println("Highest Temperature: " + maxTemperature + " Degree Celsius");
    }
 
    void showLatestReadings() {
        System.out.println("Latest Readings for " + this.location);
        for (int i = 0; i < readings.length; i++) {
            if (readings[i] != null) {
                System.out.println(readings[i].toString());
            }
        }
    }

    void reset() {
        readings = new reading[NUMBER_OF_READINGS];
        minTemperature = DEFAULT_MINIMUM_TEMPERATURE;
        maxTemperature = DEFAULT_MAXIMUM_TEMPERATURE;
        totalRainfall = 0;
    }

    static void UpdateOverallStatistics(reading r, String location) {
        if (r.temperature < overallMinTemperature) {
            overallMinTemperature = r.temperature;
            overallMinTemperatureLocation = location;
        }
        if (r.temperature > overallMaxTemperature) {
            overallMaxTemperature = r.temperature;
            overallMaxTemperatureLocation = location;
        }
    }

    static void UpdateOverallRainfallStatistics(float totalRainfall, String location) {
        if (totalRainfall > maxTotalRainfall) {
            maxTotalRainfall = totalRainfall;
            maxTotalRainfallLocation = location;
        }
    }

    static void showOverallMinTemperature() {
        System.out.println("Lowest Temperature: " + overallMinTemperature + " Degree Celsius in " + overallMinTemperatureLocation);
    }

    static void showOverallMaxTemperature() {
        System.out.println("Highest Temperature: " + overallMaxTemperature + " Degree Celsius in " + overallMaxTemperatureLocation);
    }

    static void showMaxTotalRainfall() {
        System.out.println("Max Amount of Rainfall: " + maxTotalRainfall + " mm in " + maxTotalRainfallLocation);
    }

    static void resetStations() {
        overallMaxTemperature = DEFAULT_MAXIMUM_TEMPERATURE;
        overallMaxTemperatureLocation = null;
        overallMinTemperature = DEFAULT_MINIMUM_TEMPERATURE;
        overallMinTemperatureLocation = null;
        maxTotalRainfall = 0;
        maxTotalRainfallLocation = null;
        for (int i = 0; i < stationCounter; i++) {
            stations[i].reset();
        }
    }

}
```






Spoiler





```
import static org.junit.Assert.assertEquals;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class weather_station_test {

    weather_station linz = new weather_station("Linz");
    weather_station wels = new weather_station("Wels");
    weather_station hagenberg = new weather_station("Hagenberg");
    weather_station steyr = new weather_station("Steyr");

    @Before
    public void setUp() throws Exception {
        linz = new weather_station("Linz");
        wels = new weather_station("Wels");
        hagenberg = new weather_station("Hagenberg");
        steyr = new weather_station("Steyr");
    
        linz.addReading(new reading(14, 0));
        linz.addReading(new reading(16, 34));
        
        linz.showLatestReadings();
        linz.showMaxTemperature();
        linz.showMinTemperature();
    
        wels.addReading(new reading(10, 2));
        wels.addReading(new reading(-8, 3));
        
        wels.showLatestReadings();
        wels.showMaxTemperature();
        wels.showMinTemperature();
    
        hagenberg.addReading(new reading(-20, 0));
        hagenberg.addReading(new reading(0, 0));
        
        hagenberg.showLatestReadings();
        hagenberg.showMaxTemperature();
        hagenberg.showMinTemperature();
    
        steyr.addReading(new reading(23, 23));
        steyr.addReading(new reading(21, 3213));
        
        steyr.showLatestReadings();
        steyr.showMaxTemperature();
        steyr.showMinTemperature();
        
        weather_station.showOverallMinTemperature();
        weather_station.showOverallMaxTemperature();
        weather_station.showMaxTotalRainfall();        
        weather_station.resetStations();
    }

    @After
    public void tearDown() throws Exception {
        weather_station.resetStations();
    }

    @Test
    public void testLinz() {
        assertEquals(14, linz.minTemperature, 0.000001);
        assertEquals(16, linz.maxTemperature, 0.000001);
        assertEquals(34, linz.totalRainfall, 0.000001);
    }

    @Test
    public void testWels() {
        assertEquals(-8, wels.minTemperature, 0.000001);
        assertEquals(10, wels.maxTemperature, 0.000001);
        assertEquals(5, wels.totalRainfall, 0.000001);
    }

    @Test
    public void testHagenberg() {
        assertEquals(-20, hagenberg.minTemperature, 0.000001);
        assertEquals(0, hagenberg.maxTemperature, 0.000001);
        assertEquals(0, hagenberg.totalRainfall, 0.000001);
    }

    @Test
    public void testSteyr() {
        assertEquals(21, steyr.minTemperature, 0.000001);
        assertEquals(23, steyr.maxTemperature, 0.000001);
        [COLOR=red][B]assertEquals(3213, steyr.totalRainfall, 0.000001);[/B]    }

    @Test
    public void testStatistics() {
       [COLOR=red][B] assertEquals(-20, weather_station.overallMinTemperature, 0.000001);[/B]        assertEquals("Hagenberg", weather_station.overallMinTemperatureLocation);
        assertEquals(23, weather_station.overallMaxTemperature, 0.000001);
        assertEquals("Styer", weather_station.overallMaxTemperatureLocation);
        assertEquals(3213, weather_station.maxTotalRainfall, 0.000001);
        assertEquals("Steyr", weather_station.maxTotalRainfallLocation);
    }
    
}
```






Spoiler





```
public class reading {
    float temperature; 
    float rainfall; 
    
    public reading(float temperature, float rainfall) {
        this.temperature = temperature;
        this.rainfall = rainfall;
    }

    @Override
    public String toString() {
        return temperature + " Degree Celsius, rainfall: " + rainfall + " mm";
    }

}
```



^^ Nur die beiden rot markierten Zeilem im zweiten Code-Teil liefern noch Failures im TestCase. 
1. rote Zeile: _java.lang.AssertionError: expected:<3213.0> but was:<3236.0>_
2. rote Zeile: _java.lang.AssertionError: expected:<-20.0> but was:<100.0>_

Wenn mir jemand helfen könnte, noch die beiden Kleinigkeiten auszubessern, wäre es super! 
Ist das 3213 auch nur ein Fehler, den ich ausbessern muss? Wo kommt denn das überhaupt her? Ich sehe nicht, wo dieser Wert berechnet wird.

Dann hätte ich nur noch ein paar Verständnisfragen zu den Codes ...


----------



## boss3D (22. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

So, hier ...


----------



## DarkMo (22. April 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

hehe, hatte dir grad eben scho wieder geschrieben, dass ichs mittlerweile hinbekommen hatte.


----------



## boss3D (1. Mai 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Hi, DarkMo!

Ich hätte ein neues Beispiel, wenn du Lust hast ... 

Diesmal geht's um eine ArrayList. Kannst dir gerne mal das Archiv aus dem Anhang runterladen (siehe Link unten). Das Grundgerüst habe ich bereits zusammengebastelt. Jetzt hänge ich bei der Implementierung von ein paar Methoden. 
Als erstes müsste ich mal wissen, was genau in Zeile 62 und 63 in der Klasse ArrayList nicht passt: Darf ich da wirklich einfach einen TypCast auf die Klasse selbst machen, wie's die Autokorrektur von Eclipse vorschlägt?

Dann: Was genau soll das Interface Element darstellen? Und was ist der int key, der in manchen Methoden der anderen Interfaces vorkommt? Einen Index gäb's ja auch, also wird key nicht der Index sein. 

Und wie kann ich mir die ArrayList überhaupt vorstellenb? Es ist ja nicht ein einzelnes Array. Ist es ein Array mit Arrays als Elementen? Lat google Suche gäb's auch von Java aus schon jede Menge fertige Methoden, aber so wie's aussieht, kann ich die nicht nutzen und muss mir laut Angabe alles selbst implementieren?!

Falls du ein paar Tipps dazu hast, danke im Voraus! 

*[EDIT]*
So, hab's noch ein Bisschen erweitert. Allerdings weiß ich nicht, wie viel Sinn das macht, fertige Java Methoden in (gleichnamige) eigene Methoden (die ich allerdings wegen der Interfaces so verwenden muss) zu packen ... 

*[EDIT2]
*


			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        





			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



*[EDIT3]*



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



*[EDIT4]*
Neues Beispiel ...



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.


----------



## boss3D (1. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Ich hätte mal wieder eine Aufgabe, bei der ich Hilfe gebrauchen könnte ...

Folgende Angabe:




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



Und folgende Fragen habe ich dazu:

- In Klasse ChairMember: Macht das was, dass _fee_ als nicht initialisiert  (von Eclipse) angezeigt wird? Im Konstruktor bekommt's ja dann eh einen  Wert zugewiesen.
- In Klasse Section: Selbe Frage, nur hier für _overallIncome_ und _overallCosts_ ... ?
- In Klasse Section: Kann ich eine Variable in einem Konstruktor durch  Aufsummieren in einer Schleife initialisieren, oder sollte ich besser  eine andere "Hilfsvariable" aufsummieren lassen und dann z.B. sagen:  this.overallIncome = hilfsvariable; ?
- In Klasse Section: Wie setze ich das um, dass eine Sektion andere Sektionen beinhalten kann?
- Wieso liefern meine beiden bisher erstellten Testklassen nicht true?

Danke für hilfreiche Antworten!


----------



## Anubis12334 (1. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

In der Klasse Member sind die Modifizierer falsch. Schau dir das nochmal an. 

In der Klasse Sektion, stimmt die Berechnung der Kosten?

Damit eine Sektion andere Sektions enthälst schreibst du:

private ArrayList<Section> sections;

und dann:
im Konstruktor:
sections  = new ArrayList<Section>();

hinzufügen:

public void AddSection(Section section){
sections.Add(section);
}



Die Testklasse sieht so besser aus (imho):

@Test
    public void test() {
        String testString = "Name: Hans Mueller | Income: 0 | Costs: 0 | Surplus: 0";
       assertEquals(true, testString.equals(one.toString()));
    }

Vergleich doch mal per Debugger oder Ausgabe die beiden Strings (System.out.println(one.toString()), dann kommst du sicher selber drauf.

---
Ach und rein logisch. Negative Kosten sind doch eigentlich Einnahmen!


----------



## boss3D (1. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*



Anubis12334 schrieb:


> In der Klasse Member sind die Modifizierer falsch. Schau dir das nochmal an.


In der Angabe heißt's: _"Alle Mitglieder (Klasse Member) haben einen Namen und eine eindeutige Mitgliedsnummer, die durch das System beim Anlegen eines Mitglieds automatisch und *unveränderbar vergeben* wird."_
Ich nehme daher an, du meinst, dass ich die Datenfelder von _public_ zu _private_ ändern sollte?! Das _final_ müsste schon stimmen?! Wenn ich die Datenfelder allerdings auf _private_ setze, können sie in den Subklassen nicht mehr verwendet werden. Da will ich aber drauf zugreifen. Bei den Methoden sehe ich jetzt auch keinen Fehler. Ein Konstruktor muss public sein, oder ich kann kein Objekt der Klasse erzeugen ...


Anubis12334 schrieb:


> In der Klasse Sektion, stimmt die Berechnung der Kosten?


Es geht ja darum, den Gesamtgewinn und Gesamtverlust durch alle Mitglieder der Sektion zu bestimmen. Alle Mitglieder stecken bei mir im Feld _Member[] section_. Daher habe ich mir gedacht, ich muss das Feld in einer Schleife durchlaufen und für jedes Mitglied, das dabei erwischt wird, den Gewinn und den Verlust in den entsprechenden Variablen dazuaddieren?!

Ich bin mir allerdings nicht sicher, ob ich in mein Feld Mitglieder unterschiedlicher Typen (z.B. TopAthlete, AmateurAthlete, etc.) reinpacken kann, die ja alle unterschiedliche Kosten und Gewinne verursachen. Und ich weiß auch nicht, ob ich in der Schleife direkt in _this.overallIncome_ und _this.overallCosts_ aufsummieren kann, oder ob ich das lieber in einer einfachen double Variable tun und dann nach der Schleife sagen sollte: _this.overallIncome = variable1; this.overallCosts = variable2;_ ... ?


Anubis12334 schrieb:


> Damit eine Sektion andere Sektions enthälst schreibst du:
> 
> private ArrayList<Section> sections;
> 
> ...


Ok, danke.





Anubis12334 schrieb:


> Die Testklasse sieht so besser aus (imho):
> 
> @Test
> public void test() {
> ...


Aua ...  Ja, hab's gesehen. Die MemberTest Klasse stimmt jetzt, aber in der SupportMemberTest Klasse will er für _surplus_ 0.0 und ich aber 85.0 (100 € Gewinn - 15 € Kosten).

In meiner Klasse _SupportMember_ habe ich zwar im Konstruktor nur _this.income_ und _this.costs_ angegeben, aber _this.surplus_ müsste ja durch den _super()_ Aufruf aus dem Konstruktor der _Member_ Klasse kommen?! 


Anubis12334 schrieb:


> Ach und rein logisch. Negative Kosten sind doch eigentlich Einnahmen!


Es gibt keine negativen Kosten, das war ein Fehler von mir. Auch bei der Kostenermittlung muss ich += sagen ...


----------



## Anubis12334 (2. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

ich verstehe den Sinn von private Settern&Gettern und public Attributen nicht.


----------



## boss3D (2. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Die Datenfelder aus der _Member_ Klasse will ich ja auch in den Subklassen wie z. B. _SupportMember_ benutzen können. Insofern müssen die _public_ sein. Die Getter kann ich _private_ machen, weil die anderen Klassen nur auf den Konstruktor von _Member_ zugreifen und dieser bekommt von den privaten Gettern die nötigen Daten. Hätte ich _income_, _costs_ und _surplus_ nicht im Konstruktor, dann müsste ich die Getter _public_ machen, damit auch die Subklassen darauf zugreifen können ...

^^ Soweit meine Logik. Kann man sicher disktuieren, ob's nicht anders schlauer wäre.

Auf jeden Fall bleiben meine Fragen aus dem vorigen Posting, falls da jemand Antworten hat!


----------



## boss3D (2. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

So, hab's jetzt hingekriegt, dass alles läuft. Für _surplus_ musste ich nur den entsprechenden Getter aufrufen anstatt dem Datenfeld selbst. Ich konnte auch noch ein Bisschen sinnlosen Code löschen, sodass das ganze jetzt kompakter aussieht. 

Das einzige, was mir jetzt noch fehlt, ist die TestKlasse für _Section_; da hänge ich gerade:

```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class SectionTest {

    Section sectionOne = new Section();
    
    @Test
    public void test() {
        
    }

}
```
Die Klasse Section müsste stimmen?! Was mich nur verwirrt, ist, dass ich den super() Aufruf brauche um an den Member Konstruktor zu kommen. Klar, das Member[] section Array, das die Mitglieder enthält, braucht Namen und IDs, aber die Sektion selbst doch nicht?! Wie löse ich das geschickter? 


Spoiler





```
import java.util.ArrayList;


public class Section extends Member {

    private final int size; // Größe des Sektions-Arrays
    private int allocation; // aktuelle Belegung mit Mitgliedern
    private Member[] section;
    private double overallIncome;
    private double overallCosts;
    private ArrayList<Section> sections;
    
    public Section(String firstName, String lastName, int ID, int size) {
        super(firstName, lastName, ID);
        this.size = size;
        this.allocation = 0;
        this.section = new Member[this.size];
        for (int i = 0; i < section.length; i++) {
            this.overallIncome += this.section[i].income;
            this.overallCosts += this.section[i].costs;
        }
        this.sections = new ArrayList<Section>();
    }

    public void addMember(Member m) {
        if (this.allocation < this.size) {
            this.section[this.allocation] = m;
            this.allocation++;
        } else {
            System.out.println("Member can't be added! Section already full.");
        }
    }
    
    public void AddSection(Section section) {
        if (this.allocation < this.size) {
            this.sections.add(section);
            this.allocation++;
        } else {
            System.out.println("Sub-Section can't be added! Section already full.");
        }
    }
}
```



Member:



Spoiler





```
public class Member {
    
    public final String firstName;
    public final String lastName;
    public final int ID;
    public double income;
    public double costs;
    public double surplus;
    
    public Member(String firstName, String lastName, int ID) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.ID = ID;
        this.income = this.getIncome();
        this.costs = this.getCosts();
        this.surplus = this.getSurplus();
    }
    
    public double getIncome() {        
        return this.income;        
    }
    
    public double getCosts() {        
        return this.costs;
    }
    
    public double getSurplus() {        
        return this.getIncome()-this.getCosts();
    }
    
    public String toString() {
        String result = new String();
        result = "Name: " + this.firstName + " " + this.lastName + " | Income: " + this.getIncome() + " | Costs: " + this.getCosts() + " | Surplus: " + this.getSurplus();
        return result;        
    }
```



Die Getter in Klasse Member habe ich jetzt auf _public_ gesetzt, weil man Getter wirklich immer _public_ sieht, aber funktionieren würd's auch mit _private_. Was also wirklich machen?

Sollte ich z. B. in Klasse _SupportMember_ wieder 2 Datenfelder _income_ und _costs_ anlegen und auf diese über die _public_ Getter der Klasse _Member_ zugreifen? Dafür könnte ich dann die Datenfelder von _Member_ auf _private_ setzen ...


----------



## DarkMo (2. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

getter und setter sind freilich immer public ^^ sie sollen ja eben überhaupt erstmal den zugriff auf private-variablen geben. wenn die nun selbst private sind... 

variablen sollten halt möglichst immer private sein, damit man von aussen nicht unkontrolliert drauf zugreifen kann. diesen kontrollierten zugriff ermöglichen dann die setter. puh, als bsp mal *grübel* gute frage auf anhieb. bezieht sich eben meist auf zusammenhänge zwischen den variablen. also wenn man variable A verändert, zieht das änderungen an weiteren variablen nach sich, damit die interne logik stimmt. hmm, vllt als bsp deine array list klasse da. added man ein element ist das ja auch entfernt sone art setter methode. da hatten wir dann die size mit angepasst, ggf das array erweitert usw usf. würde man hier einfach stumpf von aussen auf die daten-variable an sich zugreifen, zerhaut man sich die ganze interne logik. daher is der krams möglichst private und per public zugriffs methoden erreichbar.


----------



## boss3D (2. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Soweit habe ich das schon überprüft, dass mir ein Zugriff auf _public_ Variablen nichts ruiniert. Das doofe ist halt, dass ich dann in mind. 4 Klassen die selben _private_ Variablen anlegen müsste, um mit den _public_ Gettern aus _Member_ Werte zuweisen bzw. abholen zu können. Oder lässt sich das durch die Vererbung, die ja bei mir gegeben ist, geschickter lösen?

Also Member so:

```
public class Member {
    
    private final String firstName;
    private final String lastName;
    private final int ID;
    private double income;
    private double costs;
    
    public Member(String firstName, String lastName, int ID) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.ID = ID;
        this.income = this.getIncome();
        this.costs = this.getCosts();
        this.getSurplus();
    }
    
    public double getIncome() {        
        return this.income;        
    }
    
    public double getCosts() {        
        return this.costs;
    }
    
    public double getSurplus() {        
        return this.getIncome()-this.getCosts();
    }
    
    public String toString() {
        String result = new String();
        result = "Name: " + this.firstName + " " + this.lastName + " | Income: " + this.getIncome() + " | Costs: " + this.getCosts() + " | Surplus: " + this.getSurplus();
        return result;        
    }

}
```
Und SupportMember so:

```
public class SupportMember extends Member {

    public SupportMember(String firstName, String lastName, int ID) {
        super(firstName, lastName, ID);
        this.getIncome();
        this.getCosts();
    }

}
```
^^ Nur wie kriege ich jetzt in _income_ 100 rein und in _costs_ 15?

Und bevor der erste mit Settern in Klasse _Member_ kommt: Geht nicht! Laut Angabe dürfen da nur die 3 Getter und die toString Methode rein.


----------



## Anubis12334 (2. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

setter schreiben und this.setIncome(WERT); schreiben;


----------



## boss3D (2. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Sieher letzter Satz in meinem vorigen Posting. In _Member_ "darf" ich (laut Angabe) keine Setter machen (nur die Getter und die _toString_ Methode) und in _SupportMember_ bzw. den anderen Klassen bringt's nichts ... oder überseh' ich was in meiner Logik?


----------



## Anubis12334 (2. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Hm..ich lese da jetzt nix, dass es verboten sei andere Methoden zu schreiben. Und du musst setter schreiben, da wenn du einfach das Attribut auf public setzt, wäre das richtig schlechter Stil


----------



## boss3D (2. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Für mich klang die Angabe so, als wäre nur das erlaubt, was angegeben ist?! Quasi "whitelisting" ... 

Ok, von mir aus bastle ich Setter rein. Dass es der beste Weg wäre, musst du mir nicht sagen. Ich hab's eben wegen der Angabe nicht gemacht gehabt. Auf jeden Fall bräuchte ich dann bitte noch Hilfe beim Schreiben der _SectionTest_ Klasse. Siehe hier.


----------



## boss3D (3. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Wenn mir bei der _Section_ TestKlasse keiner helfen kann, hätte ich noch ein zweites Beispiel, wo das vielleicht geht ...




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



Das Grundgerüst sieht wohl so aus:


```
import javax.crypto.KeyGenerator;

public class FibonacciGenerator {
    
    private static KeyGenerator instance = null;
    
    [COLOR=royalblue]/**
     * Default-Konstruktor, der nicht außerhalb dieser Klasse
     * aufgerufen werden kann
     */    private FibonacciGenerator() {
        
    }
    
   [COLOR=royalblue] /**
     * Liefert die KeyGenerator-Instanz zurück
     * @return KeyGenerator-Instanz
     */    static KeyGenerator getInstance() {
        if (instance == null) {
            instance = [COLOR=red]new KeyGenerator();
        }
        return instance;        
    }
    
   [COLOR=royalblue] /**
     * Liefert einen (seit dem letzten Reset) eindeutigen Schlüssel
     * @param l 
     * @return Schlüssel
     */    long getKey() {
        
        return 0;
    }
    
   [COLOR=royalblue] /**
     * Setzt den Zahlengenerator zurück
     */    void reset() {
        
    }

}
```
Meine Fragen:

- Wo genau muss ich die Fibonacci-Berechnung reinbauen? In _getKey()_ das hier einfügen (?):

```
if (n <= 1) { 
            return n; 
} else { 
            return fib(n-1) + fib(n-2);         
}
```
Dann müsste ich aber statt _fib() getKey()_ sagen und ich weiß nicht, ob ich da Parameter in den Methodenkopf einfügen darf/soll. 
Zur dritten Fibonacci-Zahl käme ich dann wohl, wenn ich die Rekursion bei _n=2_ beginnen lassen würde?! Bzw. ist das das, was _reset()_ machen sollte? Den Generator jedesmal auf die 3te Fibonacci-Zahl setzen? Dann müsste ich ja dort nur sagen _return 2_, aber das käme mir leicht "strange" vor ...
Und für KeyGenerator musste ich ja die crypto-Bibliothek einfügen, aber nutzen mir deren Methoden in dem Beispiel irgendwas?

- Das rot markierte passt auch noch nicht. Ich könnte ein neues Objekt der Klasse mit dem Klassennamen erstellen (FibonacciGenerator), aber laut Angabe soll ja eine KeyGenerator Instanz zurückgegeben werden?!


----------



## -Phoenix- (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Hi,

KeyGenerator ist ein Singleton du kannst kein neues Obj über new erstellen, du kannst dir aber ein Obj über *getInstance* holen.
Irgendwie versteh ich deine Aufgabenstellung nicht mir ist unklar was du mit der crypto-Bib machen sollst  
Du kannst zwar der getInstance einen 
String algorithm

übergeben, aber da ist nichts von Fibonacci dabei.
Vll muss deine Klasse von KeyGenerator erben.

Ohne das crypto-Bib hätte ich jetzt gesagt:

du musst halt eine Statische Varialbe machen die dir die Rekursionstiefe speichert und bei jedem getKey() inkrementiert wird.
In getKey rufst du dann einfach fib(Rekursionstiefe) auf.
Und in reset setzt du die Rekursionstiefe auf 3.


Lg.


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Hi! Danke für die Tipps. 

Die crypto-Bibliothek habe ICH eingebunden, weil Eclipse sonst meint: _KeyGenerator cannot be resolved to a type_
In der Angabe steht eh nichts davon. Nur wie löse ich das sonst? Irgendwas will Eclipse ganz offenbar haben ...

Bei deiner restlichen Erklärung komme ich nicht ganz mit. Hast du dir das ganze ungefähr so vorgestellt (?):

```
public class FibonacciGenerator {
    
    private static int rekursionstiefe;
    [COLOR=royalblue]
    /**
     * Default-Konstruktor, der nicht außerhalb dieser Klasse
     * aufgerufen werden kann
     */    private FibonacciGenerator() {
        
    }
    
  [COLOR=royalblue]  /**
     * Liefert die KeyGenerator-Instanz zurück
     * @return KeyGenerator-Instanz
     */    static KeyGenerator getInstance() {
    [COLOR=seagreen]/* geht ohne die crypto-Bibliothek so nicht! Und ein String als Parameter wird auch verlangt! [COLOR=seagreen]
        BTW: Ist das hier nicht eine rekursive Endlosschleife? "Meine" Methode heißt ja gleich, wie die Java-Methode?! [COLOR=seagreen]*/        return KeyGenerator.getInstance(); 
    }
    
   [COLOR=royalblue] /**
     * Fibonacci Berechnung
     * @param num = Ausgabgswert
     * @return Fibonacci-Zahl
     */    private long fib(long num) {
        reset();

        if (this.getKey() <= 1) { 
            return this.getKey(); 
        } else { 
            return this.fib(this.getKey()-1) + this.fib(this.getKey()-2);         
        }
    }
    
  [COLOR=royalblue]  /**
     * Liefert einen (seit dem letzten Reset) eindeutigen Schlüssel
     * @param l 
     * @return Schlüssel
     */    public long getKey() {    
        return this.fib(rekursionstiefe++);
    }
    
   [COLOR=royalblue] /**
     * Setzt den Zahlengenerator zurück
     */    private void reset() {
        rekursionstiefe = 3;
    }

}
```
Irgendwie verstehe ich immer noch nicht ganz den Sinn von diesem ganzen Teil ... Ich soll mit dieser Klasse ein einziges Objekt erzeugen können, das dann den Schlüssel darstellt?! In der Aufgabe ist auch von Schlüsseln in der Mehrzahl die Rede, und ich dachte, Sinn vom Singleton Pattern wäre es, nur ein einziges Objekt, als einen einzigen Schlüssel, erzeugen zu können?! 

*[EDIT]*
Kann es sein, dass die Methode _getInstance()_ das Ergebnis von _getKey()_ als Instanz zurückgeben soll? 

Und was meinst du zu meinen Methoden-Modifikatoren? Passen die Sichtbarkeiten? Wenn der Satz darüber richtig ist, könnte ich ja _getKey()_ auch auf _private_ setzen. Und meine 3 Methoden außer der statischen _getInstance()_ sind alles Instanzmethoden, die ich mit _this_ aufrufen kann, oder?


----------



## -Phoenix- (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Ich hätte mir das ganze so vorgestellt.
Btw. Inkrement ist ++ nicht -- ^^
Du hast jetzt ein Singleton von FibonacciGenerator und über getKey bekommst du eine fortlaufende Fibonacci Zahl und mit reset wird wieder von vorne begonnen.
Das einzige Problem das ich sehe ist das in der Aufgabenstellung static KeyGenerator getInstance() steht, was meiner meinung nach total sinnfrei ist oder ich steh gerad irgendwie auf dem Schlauch 

```
import javax.crypto.KeyGenerator;

public class FibonacciGenerator {

    private static int rekursionstiefe = 3;
    private static FibonacciGenerator instance = null;

    /**
     * Default-Konstruktor, der nicht außerhalb dieser Klasse aufgerufen werden
     * kann
     */
    private FibonacciGenerator() {

    }

    /**
     * Liefert die KeyGenerator-Instanz zurück
     * 
     * @return KeyGenerator-Instanz
     */
    static FibonacciGenerator getInstance() {
        if (instance == null) {
            instance = new FibonacciGenerator();
        }
        return instance;
    }

    /**
     * Fibonacci Berechnung
     * 
     * @param num
     *            = Ausgabgswert
     * @return Fibonacci-Zahl
     */
    private static long fib(final int n) {
        if (n <= 1) {
            return n;
        } else {
            return fib(n - 1) + fib(n - 2);
        }
    }

    /**
     * Liefert einen (seit dem letzten Reset) eindeutigen Schlüssel
     * 
     * @param l
     * @return Schlüssel
     */
    long getKey() {
        return fib(rekursionstiefe++);
    }

    /**
     * Setzt den Zahlengenerator zurück
     */
    void reset() {
        rekursionstiefe = 3;
    }

}
```


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Habe oben noch fleißig rumeditiert, während du geschrieben hast. Ich glaube, dass mein Code jetzt sogar noch "besser" hinkäme, oder? 

Dass _getInstance()_ vom Typ KeyGenerator sein soll, ist bei mir auch das größte Problem. Das sollte doch der Klassenname sein?! Eben so, wie du's hier gemacht hast ...

*[EDIT]*
Also endgültig dann wohl so:

```
public class FibonacciGenerator {
    
    private static int rekursionstiefe;
    private static FibonacciGenerator instance = null;
    
    [COLOR=royalblue]/**
     * Default-Konstruktor, der nicht außerhalb dieser Klasse
     * aufgerufen werden kann
     */    private FibonacciGenerator() {
        
    }
    
    [COLOR=royalblue]/**
     * Liefert die KeyGenerator-Instanz zurück
     * @return KeyGenerator-Instanz
     */    static FibonacciGenerator getInstance() {
        if (instance == null) {
            instance = new FibonacciGenerator();
        }
        return instance;        
    }
    
   [COLOR=royalblue] /**
     * Fibonacci Berechnung
     * @param num = Ausgabgswert
     * @return Fibonacci-Zahl
     */    private long fib(long num) {
        this.reset();
        
        if (this.getKey() <= 1) { 
            return this.getKey(); 
        } else { 
            return this.fib(this.getKey()-1) + this.fib(this.getKey()-2);         
        }
    }
    
    [COLOR=royalblue]/**
     * Liefert einen (seit dem letzten Reset) eindeutigen Schlüssel
     * @param l 
     * @return Schlüssel
     */    public long getKey() {    
        return this.fib(rekursionstiefe++);
    }
    
    [COLOR=royalblue]/**
     * Setzt den Zahlengenerator zurück
     */    private void reset() {
        rekursionstiefe = 3;
    }

}
```


----------



## -Phoenix- (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*



boss3D schrieb:


> ...... Das sollte doch der Klassenname sein?! Eben so, wie du's hier gemacht hast ...


Einfach mal davon ausgehen das die Aufgabenstellung Falsch ist  

Das musst doch aber auch klatschen das ist ja indirekte-endlos-rekursion   fib->getkey->fib->getkey ......

```
private long fib(long num) {
         reset();
          if (this.getKey() <= 1) {
              return this.getKey();
          } else {
              return this.fib(this.getKey()-1) + this.fib(this.getKey()-2);                 
 }     
}         
public long getKey() {
             return this.fib(rekursionstiefe++);
```
Edit1: Ich würde jetzt einfach FibonacciGenerator von KeyGenerator erben lassen
Edit2: Wobei das geht gar nicht man ja keinen Super Konstruktor aufrufen.
Edit3: OK geht doch


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*



-Phoenix- schrieb:


> Einfach mal davon ausgehen das die Aufgabenstellung Falsch ist


Hab' mal schnell der Verfasserin der Aufgabe ein mail geschrieben. Vielleicht kommt ja heute noch was darauf zurück. 


-Phoenix- schrieb:


> Das musst doch aber auch klatschen das ist ja indirekte-endlos-rekursion   fib->getkey->fib->getkey ......


Habe mir schon fast gedacht, dass das ein Bisschen viele verschachtelte Methodenaufrufe sind.  


-Phoenix- schrieb:


> Ich würde jetzt einfach FibonacciGenerator von KeyGenerator erben lassen


Was genau willst du jetzt mit Vererbung machen? Ich habe mir gedacht, ich muss nur diese eine Klasse _FibonacciGenerator_ machen und dazu dann noch eine JUnit TestKlasse, in der ich dann eigentlich verschiedene Schlüssel zurückbekommen müsste?! 

BTW: Wie genau darf ich das mit dem Singleton-Ansatz aber mehreren Schlüsseln (als Instanzen) überhaupt verstehen? Siehe Sätze vorm EDIT *hier*.


----------



## -Phoenix- (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Habs bei mir mal schnell geschieben mit erben von KeyGenerator gehts  .
Der Ansatz von nen Singleton ist du holst dir eine Instanze des Objekts mit getInstance und dann kannst du auf/mit diesem Objekt arbeiten, in diesem Beispiel jetzt also dir die Fib Zahlen (getKey) holen.
Bei Singleton darf es nur höhstens 1 Instanz einer Klasse geben.


```
FibonacciGenerator fg = FibonacciGenerator.getInstance();
        System.out.println(fg.getKey());
        System.out.println(fg.getKey());
        System.out.println(fg.getKey());
        fg.reset();
        System.out.println(fg.getKey());
```
So siehts mit vererbung aus:



Spoiler





```
import javax.crypto.KeyGenerator;

public class FibonacciGenerator extends KeyGenerator{

    private static int rekursionstiefe = 3;
    private static KeyGenerator instance = null;

    /**
     * Default-Konstruktor, der nicht außerhalb dieser Klasse aufgerufen werden
     * kann
     */
    private FibonacciGenerator() {
        super(null, null, null);
    }

    /**
     * Liefert die KeyGenerator-Instanz zurück
     * 
     * @return KeyGenerator-Instanz
     */
    static KeyGenerator getInstance() {
        if (instance == null) {
            instance = new FibonacciGenerator();
        }
        return instance;
    }

    /**
     * Fibonacci Berechnung
     * 
     * @param num
     *            = Ausgabgswert
     * @return Fibonacci-Zahl
     */
    private static long fib(final int n) {
        if (n <= 1) {
            return n;
        } else {
            return fib(n - 1) + fib(n - 2);
        }
    }

    /**
     * Liefert einen (seit dem letzten Reset) eindeutigen Schlüssel
     * 
     * @param l
     * @return Schlüssel
     */
    long getKey() {
        return fib(rekursionstiefe++);
    }

    /**
     * Setzt den Zahlengenerator zurück
     */
    void reset() {
        rekursionstiefe = 3;
    }

}
```


```
public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        
        FibonacciGenerator fg = (FibonacciGenerator)FibonacciGenerator.getInstance();
        System.out.println(fg.getKey());
        System.out.println(fg.getKey());
        System.out.println(fg.getKey());
        fg.reset();
        System.out.println(fg.getKey());
    }

}
```


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Das mit der Vererbung sieht interessant aus! Machen wir's besser so, dann müssen wir keine Methoden-Namen "mutwillig" ändern ... 

Main soll ich keine machen, nur eine JUnit TestKlasse. Wenn ich in diese schreibe ...

```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class FibonacciGeneratorTest {

    FibonacciGenerator key = (FibonacciGenerator) FibonacciGenerator.getInstance();
    
    @Test
    public void test() {
        System.out.println(key.getKey());
        System.out.println(key.getKey());
        System.out.println(key.getKey());
        System.out.println(key.getKey());
    }

}
```
... dann bekomme ich als Ausgabe 0 2 2 2. Kann das stimmen? Kommt mir leicht "Spanisch" vor. Ich hätte mit allen möglichen verschiedenen Schlüsselwerten gerechnet. Oder liegt das jetzt daran, dass es immer die selbe Instanz ist?


----------



## -Phoenix- (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

eigentlich darf da nicht 0 2 2 2 kommen also wenn ich es bei mir mit main laufen lassen und noch ein paar mehr syso's mache sieht das so aus
2
3
5 -> Reset
2
3
5
8
13

An der Instanz darf es ja nicht liegen das MUSS ja immer die gleiche sein  
Mach mal das 
FibonacciGenerator key = (FibonacciGenerator) FibonacciGenerator.getInstance(); 

Entweder direkt in die Testmethode oder in die setUp() Methode.


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Habe ich eh so, ändert aber nichts ... 




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



Hast du im eigentlichen Code noch was anders?


Spoiler





```
import javax.crypto.KeyGenerator;

public class FibonacciGenerator extends KeyGenerator {
    
    private static int recursionDepth;
    private static FibonacciGenerator instance = null;
    
    [COLOR=royalblue]/**
     * Default-Konstruktor, der nicht außerhalb dieser Klasse
     * aufgerufen werden kann
     */    private FibonacciGenerator() {
        super(null, null, null);
    }
    
   [COLOR=royalblue] /**
     * Liefert die KeyGenerator-Instanz zurück
     * @return KeyGenerator-Instanz
     */    static KeyGenerator getInstance() {
        if (instance == null) {
            instance = new FibonacciGenerator();
        }
        return instance;        
    }
    
   [COLOR=royalblue] /**
     * Fibonacci Berechnung
     * @param num = Ausgabgswert
     * @return Fibonacci-Zahl
     */    private long fib(final long num) {
        this.reset();
        
        if (num <= 1) { 
            return num; 
        } else { 
            return this.fib(num-1) + this.fib(num-2);         
        }
    }
    
   [COLOR=royalblue] /**
     * Liefert einen (seit dem letzten Reset) eindeutigen Schlüssel
     * @param l 
     * @return Schlüssel
     */    public long getKey() {    
        return this.fib(recursionDepth++);
    }
    
   [COLOR=royalblue] /**
     * Setzt den Zahlengenerator zurück
     */    private void reset() {
        recursionDepth = 3;
    }

}
```


----------



## -Phoenix- (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

wie wärs wenn du nicht immer 
this.reset(); machen würdest 

ahja und 
recursionDepth noch initial auf 3 setzten sonst bekommst du als erstes immer 0


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Ok, danke! Jetzt bekomme ich auch die ganzen Fibonacci-Zahlen raus. 

Eine Frage noch: Du hast "alles" mit _static_ Methoden gelöst, ich hab's ohne _static_ Attribut und dafür mit _this_ Aufruf gemacht. Soweit ich mich in Java auskenne, hast du also Klassen-Methoden gemacht und ich Instanz-Methoden?! Funktionieren tut scheinbar beides, aber was wäre jetzt der bessere Weg?

Und kannst mir bitte noch verraten, ob meine Methoden-Modifikatoren (für die Sichtbarkeit) stimmen? Code siehe voriges Posting. Nur vor _void reset()_ darfst du dir ein _public_ hindenken.


----------



## -Phoenix- (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

static KeyGenerator getInstance() das würde ich dann auch noch Public machen. default ist nicht so pralle 
private static int recursionDepth; da kannst du auch das static weglassen
Ob man jetzt fib() static oder nicht static machst ist eigentlich egal. Ich habs halt static gemacht da diese Methode ja nicht von außen Sichtbar ist und eine Klassen Methode reicht.(Nen Paar Byte im Ram gespart )

Sonst siehts gut aus


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Ja, aber semantisch kann's ja nicht völlig egal sein, ob ich irgendwas zu einer statischen Klassen-Methode mache, oder eben eine Instanz-Methode mache?! In dem Beispiel kann ich es mir vielleicht aussuchen, aber immer geht das nicht?! Wovon hängt's ab? Das wäre noch interessant. Selbes auch bei Klassen- und Instanz-Variablen. Wann was nehmen?
----------

Ansonsten bräuchte ich immer noch Hilfe bei der Section TestKlasse aus dem vorigen Beispiel ... _*please! ... lieb schau*_ 
Angabe hier.


----------



## -Phoenix- (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Wenn du in einer Methode Attribute eines Objekts veränderst, dann kannst du das nur in normalen Methoden machen.
Wenn du aber in einer Methode Attribute einer Klasse(static Attribute) verändern willst oder gar nichts verändern willst dann machst du das in einer Klassen Methode.

Klassenvariablen definieren Globale Variablen, also für alle Objekte dieser Klasse steht das gleiche in dieser Variable. z.B. Datenbankverbindung, ObjectCounter
Instanz-Variablen sind die Eigenschaften von Objekten. Und jedes Objekt kann unterschiedliche Eigenschaften haben. 

Ich hoffe das hat dir geholfen,sonst frag einfach, so jetzt man den anderen Thread anschauen 
ah ne ist ja sogar der gleiche Thread ^^


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Ok, habe jetzt noch das _static_ bei _int recursionDepth_ weggelöscht und dafür in den Methoden mit _this_ aufgerufen, also als Instanzvariable, damit alles besser "zusammenpasst" (in meiner Version). 

Das andere Beispiel ist eh im selben Thread, nur weiter vorne ... 

*[EDIT]*
Hier nochmal der gesamte Code in aktuellster Form (damit du nicht alles zusammensuchen musst):


Spoiler



Member:

```
public class Member {
    
    private final String firstName;
    private final String lastName;
    private final int ID;
    private double income;
    private double costs;
    
    public Member(String firstName, String lastName, int ID) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.ID = ID;
        this.income = this.getIncome();
        this.costs = this.getCosts();
        this.getSurplus();
    }
    
    public void setIncome(double income) {        
        this.income = income;        
    }
    
    public double getIncome() {        
        return this.income;        
    }
    
    public void setCosts(double costs) {        
        this.costs = costs;        
    }
    
    public double getCosts() {        
        return this.costs;
    }
    
    public double getSurplus() {        
        return this.getIncome()-this.getCosts();
    }
    
    public String toString() {
        String result = new String();
        result = "Name: " + this.firstName + " " + this.lastName + " | Income: " + this.getIncome() + " | Costs: " + this.getCosts() + " | Surplus: " + this.getSurplus();
        return result;        
    }

}
```
SupportMember:

```
public class SupportMember extends Member {

    public SupportMember(String firstName, String lastName, int ID) {
        super(firstName, lastName, ID);
        this.setIncome(100);
        this.setCosts(15);
    }

}
```
ActiveMember:

```
public class ActiveMember extends Member {

    public int activity;
    
    public ActiveMember(String firstName, String lastName, int ID, int activity) {
        super(firstName, lastName, ID);
        if (this.activity < 0 || this.activity > 10) { // falls ungültige Aktivität angegeben wird
            this.activity = 0;
        } else {
            this.activity = activity;
        }
    }

}
```
TopAthlete

```
public class TopAthlete extends ActiveMember {

    public TopAthlete(String firstName, String lastName, int ID, int activity) {
        super(firstName, lastName, ID, activity);
        this.setIncome(120);
        this.setCosts(this.activity * 10);
    }

}
```
AmateurAthlete

```
public class AmateurAthlete extends ActiveMember {

    public AmateurAthlete(String firstName, String lastName, int ID, int activity) {
        super(firstName, lastName, ID, activity);
        this.setIncome(300);
        this.setCosts(this.activity * 1.5);
    }

}
```
Trainer

```
public class Trainer extends ActiveMember {

    public Trainer(String firstName, String lastName, int ID, int activity) {
        super(firstName, lastName, ID, activity);
        this.setIncome(120);
        this.setCosts(this.activity * 50);
    }

}
```
ChairMember

```
public class ChairMember extends Member {
    
    private int expertise;

    public ChairMember(String firstName, String lastName, int ID, int expertise) {
        super(firstName, lastName, ID);
        if (this.expertise < 0 || this.expertise > 10) { 
            this.expertise = 0;
        } else {
            this.expertise = expertise;
        }
        this.setIncome(this.expertise * 100);
        this.setCosts((this.getIncome() * 20) / 100);
    }

}
```
Section

```
import java.util.ArrayList;


public class Section extends Member {

    private final int size; // Größe des Sektions-Arrays
    private int allocation; // aktuelle Belegung mit Mitgliedern
    private Member[] section;
    private double overallIncome;
    private double overallCosts;
    private ArrayList<Section> sections;
    
    public Section(String firstName, String lastName, int ID, int size) {
        super(firstName, lastName, ID);
        this.size = size;
        this.allocation = 0;
        this.section = new Member[this.size];
        for (int i = 0; i < section.length; i++) {
            this.overallIncome += this.section[i].getIncome();
            this.overallCosts += this.section[i].getCosts();
        }
        this.sections = new ArrayList<Section>();
    }

    public void addMember(Member m) {
        if (this.allocation < this.size) {
            this.section[this.allocation] = m;
            this.allocation++;
        } else {
            System.out.println("Member can't be added! Section already full.");
        }
    }
    
    public void AddSection(Section section) {
        if (this.allocation < this.size) {
            this.sections.add(section);
            this.allocation++;
        } else {
            System.out.println("Sub-Section can't be added! Section already full.");
        }
    }
}
```
MemberTest

```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class MemberTest {

    Member one = new Member("Hans", "Mueller", 12); // 12 = ID
    
    @Test
    public void test() {
        String testString = "Name: Hans Mueller | Income: 0.0 | Costs: 0.0 | Surplus: 0.0";

        assertEquals(true, testString.equals(one.toString()));
    }

}
```
SupportMemberTest

```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class SupportMemberTest {

    SupportMember supportOne = new SupportMember("Hans", "Mueller", 12);
    
    @Test
    public void test() {
        String testString = "Name: Hans Mueller | Income: 100.0 | Costs: 15.0 | Surplus: 85.0";

        assertEquals(true, testString.equals(supportOne.toString()));
    }

}
```
ActiveMemberTest

```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class ActiveMemberTest {

    ActiveMember activeOne = new ActiveMember("Hans", "Meier", 14, 8); // 14 = ID, 8 = Aktivität
    
    @Test
    public void test() {
        String testString = "Name: Hans Meier | Income: 0.0 | Costs: 0.0 | Surplus: 0.0";
        
        assertEquals(true, testString.equals(activeOne.toString()));
    }

}
```
TopAthleteTest

```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class TopAthleteTest {

    TopAthlete topAthleteOne = new TopAthlete("Franz", "Berger", 43, 4); // 43 = ID, 4 = Aktivität
    
    @Test
    public void test() {
        String testString = "Name: Franz Berger | Income: 120.0 | Costs: 40.0 | Surplus: 80.0";

        assertEquals(true, testString.equals(topAthleteOne.toString()));
    }

}
```
AmateurAthleteTest

```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class AmateurAthleteTest {

    AmateurAthlete amateurAthleteOne = new AmateurAthlete("Sepp", "Mueller", 28, 1); // 28 = ID, 1 = Aktivität
    
    @Test
    public void test() {
        String testString = "Name: Sepp Mueller | Income: 300.0 | Costs: 1.5 | Surplus: 298.5";

        assertEquals(true, testString.equals(amateurAthleteOne.toString()));
    }

}
```
TrainerTest

```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class TrainerTest {

    Trainer trainerOne = new Trainer("Anton", "Gruber", 32, 3); // 32 = ID, 3 = Aktivität
    
    @Test
    public void test() {
        String testString = "Name: Anton Gruber | Income: 120.0 | Costs: 150.0 | Surplus: -30.0";

        assertEquals(true, testString.equals(trainerOne.toString()));
    }

}
```
ChairMemberTest

```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class ChairMemberTest {

    ChairMember chairMemberOne = new ChairMember("Fritz", "Wallner", 65, 10); // 32 = ID, 10 = Kompetenzwert
    
    @Test
    public void test() {
        String testString = "Name: Fritz Wallner | Income: 1000.0 | Costs: 200.0 | Surplus: 800.0";
        System.out.println(chairMemberOne.toString());
        assertEquals(true, testString.equals(chairMemberOne.toString()));
    }

}
```
SectionTest

```
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class SectionTest {

    Section sectionOne = new Section();
    
    @Test
    public void test() {
        
    }

}
```


----------



## DarkMo (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

na das mit static musste doch nu wissen ^^ da haben wir doch dieses voll ätzende bsp da durchgenommen, wo wir 0 plan hatt (wie so oft ^^). nochmal zur verdeutlichung:

static methoden: du brauchst keine objekt-instanz (myClass myObj = new myClass() der klasse anlegen, um auf die methode zuzugreifen, sondern du greifst über den klassennamen ganz allgemein darauf zu (statt myObj.methode(); eben myClass.methode(). bsp: bestes beispiel dafür sind so math-klassen - von denen musst du auch kein objekt anlegen -> math.abs(var); für den absolutwert einer variablen (und nicht math mathObj = new math(); mathObj.abs(var).

static variablen: gelten objektübergreifend, wie phoenix ja schon schön "be-beispielt" hat ^^ du hast 2 objekte der selben klasse, in obj1 erhält die staticVar den wert 1, in obj2 darauf allerdings den wert 2. greift man nun über obj1 auf staticVar zu, so bekommt man die von ob2 gesetzte 2 ausgegeben.


----------



## -Phoenix- (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Was brauchst du jetzt eigentlich noch in SectionTest ?
Einfach jetzt ein paar Testfälle schreiben. 
-> Mitglieder hinzufügen und dann Ein-/Ausgaben berrechen


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Ja, genau. Ein paar Mitglieder in die Section einfügen, aber auch andere Sections in eine _Section_ einfügen ...

JUnit Testfälle mit assertEquals. Bei mir scheitert's eben daran, dass mein _Section_ Konstruktor die Daten für einzelne User (also Namen, IDs ... als Parameter) erwartet, obwohl ich die eigentlich für die Sektion selbst gar nicht brauche?! Ich will nur User, egal wie die heißen, in die _Section_ einfügen. 

K. A. wie ich das angehen soll ... 

Ich habe dir BTW *hier* nochmal den ganzen Code gepostet.
------------


DarkMo schrieb:


> na das mit static musste doch nu wissen ^^ da  haben wir doch dieses voll ätzende bsp da durchgenommen, wo wir 0 plan  hatt (wie so oft ^^).


Aua ... ja, ja, die Wetterstation ... ich erinnere mich. 


DarkMo schrieb:


> nochmal zur verdeutlichung:
> 
> static  methoden: du brauchst keine objekt-instanz (myClass myObj = new  myClass() der klasse anlegen, um auf die methode zuzugreifen, sondern  du greifst über den klassennamen ganz allgemein darauf zu (statt  myObj.methode(); eben myClass.methode(). bsp: bestes beispiel dafür  sind so math-klassen - von denen musst du auch kein objekt anlegen ->  math.abs(var); für den absolutwert einer variablen (und nicht math  mathObj = new math(); mathObj.abs(var).
> 
> static variablen:  gelten objektübergreifend, wie phoenix ja schon schön "be-beispielt" hat  ^^ du hast 2 objekte der selben klasse, in obj1 erhält die staticVar  den wert 1, in obj2 darauf allerdings den wert 2. greift man nun über  obj1 auf staticVar zu, so bekommt man die von ob2 gesetzte 2  ausgegeben.


Danke, hab's verstanden.


----------



## -Phoenix- (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

ja dann ändere den Konstruktor oder füge einen weiteren Konstruktor hinzu.


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Hab's ja schon so probiert, aber das lässt Eclipse alles nicht zu:

```
import java.util.ArrayList;


public class Section extends Member {

    private final int size; // Größe des Sektions-Arrays
    private int allocation; // aktuelle Belegung mit Mitgliedern
    private Member[] section;
    private double overallIncome;
    private double overallCosts;
    private ArrayList<Section> sections;
    
    public Section(String firstName, String lastName, int ID, int size) {
        super(firstName, lastName, ID);
        this.size = size;
        this.allocation = 0;
        this.section = new Member[this.size];
        for (int i = 0; i < section.length; i++) {
            this.overallIncome += this.section[i].getIncome();
            this.overallCosts += this.section[i].getCosts();
        }
        this.sections = new ArrayList<Section>();
    }

    [COLOR=royalblue][B]public Section() {
        this();
    }[/B]
    public void addMember(Member m) {
        if (this.allocation < this.size) {
            this.section[this.allocation] = m;
            this.allocation++;
        } else {
            System.out.println("Member can't be added! Section already full.");
        }
    }
    
    public void AddSection(Section section) {
        if (this.allocation < this.size) {
            this.sections.add(section);
            this.allocation++;
        } else {
            System.out.println("Sub-Section can't be added! Section already full.");
        }
    }
}
```
Den Test könnte ich ungefähr so angehen, aber statt dem _null_ müsste ich dann auch wieder Mitglieder-Namen und IDs angeben ... 

```
import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;


public class SectionTest {

    Section sectionOne = new Section();
    
    @Before
    public void setup() {
        sectionOne.addMember(null);
        sectionOne.addMember(null);
        sectionOne.addMember(null);
    }
    
    @Test
    public void test() {
        
    }

}
```
^^ Außerdem sollen ja die Mitglieder verschiedene Typen haben! Geht das überhaupt bei meinem Code, dass ich da z.B. einen Trainer, einen ActiveMember und einen AmateurAthlete einfüge?

So jedenfalls nicht:

```
sectionOne.addMember(Trainer);
```


----------



## -Phoenix- (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

das ist auch wieder rekursion
*public Section() {         this();     }* 
mach einfach public Section() { }

und in test dann 
sectionOne.addMember(new Member("hans","wurst",1);
....
...
..
Wie ist das mit Section's von Section gemeint du hast eine Section mit Sections drin und in diesen Sections sind dann wieder Member ?


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*



-Phoenix- schrieb:


> das ist auch wieder rekursion
> *public Section() {         this();     }*
> mach einfach public Section() { }


Ohne irgendwas drinnen funktioniert's nicht. Da kommt vom Eclipse: _Implicit super constructor Member() is undefinied. Must explicitly invoke another constructor_ 


-Phoenix- schrieb:


> und in test dann
> sectionOne.addMember(new Member("hans","wurst",1);
> ....
> ...
> ..


Hab's jetzt erstmal so gelöst:

```
import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;


public class SectionTest {

    Section sectionOne = new Section();
    
    Trainer trainerOne = new Trainer("Anton", "Gruber", 32, 3);
    AmateurAthlete amateurAthleteOne = new AmateurAthlete("Sepp", "Mueller", 28, 1);
    ChairMember chairMemberOne = new ChairMember("Fritz", "Wallner", 65, 10);
    
    Section sectionTwo = new Section();
    Section sectionThree = new Section();
    
    @Before
    public void setup() {
        sectionOne.addMember(trainerOne);
        sectionOne.addMember(amateurAthleteOne);
        sectionOne.addMember(chairMemberOne);
        sectionOne.addSection(sectionTwo);
        sectionOne.addSection(sectionThree);
    }
    
    @Test
    public void test() {
        
    }

}
```
^^ Natürlich muss ich auch in _sectionTwo_ und _sectionThree_ noch Mitglieder einfügen. Und die Testfälle schreiben ...


-Phoenix- schrieb:


> Wie ist das mit Section's von Section gemeint du hast eine Section mit Sections drin und in diesen Sections sind dann wieder Member ?


Ja, genau. 

Das mit dem _Section()_ Konstruktor müsste ich jetzt noch lösen, dann könnte ich meine Testfälle fertig schreiben ...
*
[EDIT]*
So kannst du dir das mit den Sections in einer Section jetzt vorstellen:


Spoiler





```
import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;


public class SectionTest {

    Section sectionOne = new Section();
    
    Trainer trainerOne = new Trainer("Anton", "Gruber", 32, 3);
    AmateurAthlete amateurAthleteOne = new AmateurAthlete("Sepp", "Mueller", 28, 1);
    ChairMember chairMemberOne = new ChairMember("Fritz", "Wallner", 65, 10);
    
    Section sectionTwo = new Section();
    
    TopAthlete topAthleteOne = new TopAthlete("Franz", "Berger", 43, 4);
    SupportMember supportMemberOne = new SupportMember("Hans", "Mueller", 12);
    
    Section sectionThree = new Section();
    
    TopAthlete topAthleteTwo = new TopAthlete("Hans", "Wurst", 17, 6);
    AmateurAthlete amateurAthleteTwo = new AmateurAthlete("Peppi", "Berger", 76, 81);
    
    @Before
    public void setup() {
        sectionOne.addMember(trainerOne);
        sectionOne.addMember(amateurAthleteOne);
        sectionOne.addMember(chairMemberOne);
        
        sectionTwo.addMember(topAthleteOne);
        sectionTwo.addMember(supportMemberOne);
        
        sectionThree.addMember(topAthleteTwo);
        sectionThree.addMember(amateurAthleteTwo);
        
        sectionOne.addSection(sectionTwo);
        sectionOne.addSection(sectionThree);
    }
    
    @Test
    public void test() {
        
    }

}
```


----------



## -Phoenix- (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

In den Section Konstruktor kannst du ja dan fast das gleiche wie in addSection schreiben.


```
Section(Section section) {
        if (this.allocation < this.size) {
            this.sections.add(section);
            this.allocation++;
        } else {
            Throw new IrgendwasException ("Sub-Section can't be added! Section already full.");
        }
}
```


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Auch damit bekomme ich vom Eclipse immer noch den selben Error (siehe voriges Posting am Anfang) ...

Außerdem soll dieser Ausdruck ...

```
Section sectionOne = new Section();
```
... unabhängig davon sein, ob ein Mitglied oder eine andere Sektion hinzugefügt wird. So würde ich mir das wünschen.


----------



## -Phoenix- (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Das Problem ist halt das Section von Member erbt. Muss das so sein ? Ist für ich irgendwie nicht logisch. Wenn die vererbung nicht wäre dann würde es keine Fehler geben.


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

^^ Aus der Angabe geht das nicht wirklich hervor, wer von wem erben muss. Zumindest die Mitglieder sollten nach meiner Logik alle von Member erben. Bei der Section kann man diskutieren ...

Nur wie würde die Klasse Section dann ausschauen?

```
import java.util.ArrayList;


public class Section {

    private final int size; // Größe des Sektions-Arrays
    private int allocation; // aktuelle Belegung mit Mitgliedern
    private Member[] section;
    private double overallIncome;
    private double overallCosts;
    private ArrayList<Section> sections;
    
    [COLOR=royalblue][B]public Section(int size)[/B] {
        this.size = size;
        this.allocation = 0;
        this.section = new Member[this.size];
        for (int i = 0; i < section.length; i++) {
            this.overallIncome += this.section[i].getIncome();
            this.overallCosts += this.section[i].getCosts();
        }
        this.sections = new ArrayList<Section>();
    }

    public void addMember(Member m) {
        if (this.allocation < this.size) {
            this.section[this.allocation] = m;
            this.allocation++;
        } else {
            System.out.println("Member can't be added! Section already full.");
        }
    }
    
    public void addSection(Section section) {
        if (this.allocation < this.size) {
            this.sections.add(section);
            this.allocation++;
        } else {
            System.out.println("Sub-Section can't be added! Section already full.");
        }
    }
}
```
^^ So könnte man's dann doch machen, oder?

Und dann in der TestKlasse noch die Section Größe als Parameter einfügen:

```
import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;


public class SectionTest {

    Section sectionOne = new [COLOR=royalblue][B]Section(5)[/B];
    
    Trainer trainerOne = new Trainer("Anton", "Gruber", 32, 3);
    AmateurAthlete amateurAthleteOne = new AmateurAthlete("Sepp", "Mueller", 28, 1);
    ChairMember chairMemberOne = new ChairMember("Fritz", "Wallner", 65, 10);
    
    Section sectionTwo = new [COLOR=royalblue][B]Section(2)[/B];
    
    TopAthlete topAthleteOne = new TopAthlete("Franz", "Berger", 43, 4);
    SupportMember supportMemberOne = new SupportMember("Hans", "Mueller", 12);
    
    Section sectionThree = new [COLOR=royalblue][B]Section(4)[/B];
    
    TopAthlete topAthleteTwo = new TopAthlete("Hans", "Wurst", 17, 6);
    AmateurAthlete amateurAthleteTwo = new AmateurAthlete("Peppi", "Berger", 76, 81);
    
    @Before
    public void setup() {
        sectionOne.addMember(trainerOne);
        sectionOne.addMember(amateurAthleteOne);
        sectionOne.addMember(chairMemberOne);
        
        sectionTwo.addMember(topAthleteOne);
        sectionTwo.addMember(supportMemberOne);
        
        sectionThree.addMember(topAthleteTwo);
        sectionThree.addMember(amateurAthleteTwo);
        
        sectionOne.addSection(sectionTwo);
        sectionOne.addSection(sectionThree);
    }
    
    @Test
    public void test() {
        
    }

}
```
Dann bleiben mir zu dem Beispiel nur noch 2 Fragen:

1.) In Klasse _Section_ sind _overallIncome_ und _overallCosts_ im Eclipse gelb unterwellt mit der Meldung: _The value of the field Section.overallIncome (bzw. Section.overallCosts) is never used_ ... Macht das was? Ist ja nur ein _warning_ und kein _error_, aber stört mich irgendwie trotzdem ...
2.) In Klasse _Member_ (siehe hier am Anfang des Spoilers) habe ich das selbe mit _ID_


----------



## boss3D (4. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

So habe ich jetzt den gesamten Section Test gelöst:


Spoiler





```
import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;


public class SectionTest {

    Section sectionOne = new Section(3);
    
    Trainer trainerOne = new Trainer("Anton", "Gruber", 32, 3);
    AmateurAthlete amateurAthleteOne = new AmateurAthlete("Sepp", "Mueller", 28, 1);
    ChairMember chairMemberOne = new ChairMember("Fritz", "Wallner", 65, 10);
    
    Section sectionTwo = new Section(5);
    
    TopAthlete topAthleteOne = new TopAthlete("Franz", "Berger", 43, 4);
    SupportMember supportMemberOne = new SupportMember("Hans", "Mueller", 12);
    
    Section sectionThree = new Section(4);
    
    TopAthlete topAthleteTwo = new TopAthlete("Hans", "Wurst", 17, 6);
    AmateurAthlete amateurAthleteTwo = new AmateurAthlete("Peppi", "Berger", 76, 81);
    
    @Before
    public void setup() {
        sectionOne.addMember(trainerOne);
        sectionOne.addMember(amateurAthleteOne);
        sectionOne.addMember(chairMemberOne);
        
        sectionTwo.addMember(topAthleteOne);
        sectionTwo.addMember(supportMemberOne);
        
        sectionThree.addMember(topAthleteTwo);
        sectionThree.addMember(amateurAthleteTwo);
        
        sectionOne.addSection(sectionTwo);
        sectionOne.addSection(sectionThree);
    }
    
    @Test
    public void testMemberAddFailure() {
        [COLOR=royalblue][B]assertEquals("Member can't be added! Section already full.", sectionOne.addMember(topAthleteOne));    [/B]      
    }
    
    @Test
    public void testMemberAddSuccess() {        
        [COLOR=royalblue][B]assertEquals(true, (sectionTwo.overallIncome == 220.0 && sectionTwo.overallCosts == 55.0)); [/B]    }
    
    @Test
    public void testSectionAddFailure() {
       [COLOR=royalblue][B] assertEquals("Sub-Section can't be added! Section already full.", sectionOne.addSection(sectionThree))[/B];
    }
    
    @Test
    public void testSectionAddSuccess() {
        sectionTwo.addSection(sectionOne);
        [COLOR=royalblue][B]assertEquals(true, (sectionTwo.overallIncome == 1640.0 && sectionTwo.overallCosts == 406.5));[/B]    }

}
```



^^ Nur wie soll ich das mit den Strings lösen? String und Objekt kann man ja nicht vergleichen ... 

Und die anderen beiden Tests mit den Einnahmen und Kosten liefern mir beide _false_ statt _true_ weil in Klasse _Section_ in Zeile 18 angeblich eine NullPointerException vorliegt. Sieht einer das Problem (?):


Spoiler





```
import java.util.ArrayList;


public class Section {

    private final int size; // Größe des Sektions-Arrays
    private int allocation; // aktuelle Belegung mit Mitgliedern
    private Member[] section;
    public double overallIncome;
    public double overallCosts;
    private ArrayList<Section> sections;
    
    public Section(int size) {
        this.size = size;
        this.allocation = 0;
        this.section = new Member[this.size];
        for (int i = 0; i < section.length; i++) {
            [COLOR=royalblue][B]this.overallIncome += this.section[i].getIncome();[/B] [COLOR=seagreen]// Zeile 18            [COLOR=royalblue][B]this.overallCosts += this.section[i].getCosts(); [/B][COLOR=seagreen]// Zeile 19        }
        this.sections = new ArrayList<Section>();
    }

    public void addMember(Member m) {
        if (this.allocation < this.size) {
            this.section[this.allocation] = m;
            this.allocation++;
        } else {
            System.out.println("Member can't be added! Section already full.");
        }
    }
    
    public void addSection(Section section) {
        if (this.allocation < this.size) {
            this.sections.add(section);
            this.allocation++;
        } else {
            System.out.println("Sub-Section can't be added! Section already full.");
        }
    }
    
}
```



^^ Der Fehler liegt ganz sicher im Konstruktor von _Section_, weil ich alle anderen Klassen erfolgreich getestet habe.

_getIncome()_ und _getCosts()_ sind BTW Getter aus der Klasse _Member_:


Spoiler





```
public class Member {
    
    private final String firstName;
    private final String lastName;
    private final int ID;
    private double income;
    private double costs;
    
    public Member(String firstName, String lastName, int ID) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.ID = ID;
        this.income = this.getIncome();
        this.costs = this.getCosts();
        this.getSurplus();
    }
    
    public void setIncome(double income) {        
        this.income = income;        
    }
    
    [COLOR=royalblue][B]public double getIncome() {        
        return this.income;        
    }[/B]    
    public void setCosts(double costs) {        
        this.costs = costs;        
    }
    
    [COLOR=royalblue][B]public double getCosts() {        
        return this.costs;
    }[/B]    
    public double getSurplus() {        
        return this.getIncome()-this.getCosts();
    }
    
    public String toString() {
        String result = new String();
        result = "Name: " + this.firstName + " " + this.lastName + " | Income: " + this.getIncome() + " | Costs: " + this.getCosts() + " | Surplus: " + this.getSurplus();
        return result;        
    }

}
```


----------



## -Phoenix- (5. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Zu 1. Entweder machst du bei addMember in Section einen Rückgabewert hin oder du wirfst eine Exception, dann kannst du das mit Unit Tests prüfen.
Zu 2. Du schreibst ja auch keine Member ins Array, im Array wird nur null stehen. 
this.section = new Member[this.size]; Dabei wird ja immer der alte Wert/Inhalt von section überschieben


----------



## boss3D (5. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Zuerst zu 2.:
Ich habe schon gedacht, dass ich die Member der Reihe nach ins Array einfüge?! Auch der Index wird ja nach jedem Einfügen immer schön um 1 erhöht, damit das nächste Mitglied nicht das vorige überschreibt:

```
public boolean addMember([COLOR=royalblue][B]Member m[/B]) {
        if (this.allocation < this.size) {
            [COLOR=royalblue][B]this.section[this.allocation] = m;[/B]            [COLOR=royalblue][B]this.allocation++;[/B]        } else {
            System.out.println("Member can't be added! Section already full.");
            return false;
        }
        return true;
    }
```
Zu 1.: Ok, hab's jetzt mit Rückgabewert gemacht, aber in der Testklasse jammert er immer noch bei allen 4 Testfällen wegen der NullPointerException. 

Die kommt von hier:

```
public Section(int size) {
        this.size = size;
        this.allocation = 0;
        this.section = new Member[this.size];
        for (int i = 0; i < section.length; i++) {
            [COLOR=royalblue][B]this.overallIncome += this.section[i].getIncome();
            this.overallCosts += this.section[i].getCosts();[/B]        }
        this.sections = new ArrayList<Section>();
    }
```


----------



## -Phoenix- (5. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Wenn du den Konstruker aufrust dann erstellt du ja ein Array (section) für Members ABER in dem Array steht nichts drin.
Die For-Schleife ist also total sinnfrei, durch ein leeres Array zu iterieren und dabei was zu erwarten (außer Fehler) ist nicht gerad sinnvoll......
        for (int i = 0; i < section.length; i++) 
{   
*this.overallIncome += this.section.getIncome();*_ // Zeile 18 
*this.overallCosts += this.section.getCosts(); *// Zeile 19 
}_


----------



## boss3D (5. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Und wie ändere ich das? Soll ich meine _addMember()_ Methode im Konstruktor aufrufen? 

Ich dachte, durch den Aufruf von _addMember()_ in der Testklasse werden die Mitglieder in die Section eingefügt, die ja intern durch das Array verwaltet wird?!

DarkMo und ich hatten vor kurzem eine ArrayList, wo das Hinzufügen genau so funktioniert hat:

```
public ArrayList() { 
        this.initCap = 6;
        this.realCap = this.initCap;
        [COLOR=royalblue][B]this.list = new Element[this.realCap];[/B]        this.size = 0;
    }
    
    /**
     * Konstruktor 2 mit selbstgewählter Kapazität
     * @param capacity = beliebige Kapazität
     */
    public ArrayList(int capacity) { 
        int minCap = 4; // selbstgewählte Minimum Kapazität der Liste
        if (capacity > minCap) {
            this.initCap = capacity;
            this.realCap = capacity;
        } else {
            this.initCap = 6;
            this.realCap = 6;
        }
        [COLOR=royalblue][B]this.list = new Element[this.realCap];[/B]        this.size = 0;
    }

    /**
     * Füge Elemente am Ende der Liste hinzu
     * @param element = hinzuzufügendes Element
     */
    public void add(Element element) {
        if (this.size == this.realCap) {
            this.expandList();
            [COLOR=royalblue][B]this.list[this.size] = element;[/B]        } else {
            [COLOR=royalblue][B]this.list[this.size] = element;[/B] // Element am Ende der Liste einfügen
        }
        this.size++; // Zähler für Elemente um 1 erhöhen
    }
```
^^ Oder übersehe ich hier einen bedeutenden Unterschied?


----------



## -Phoenix- (5. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Zur verdeutlichung :
1. Deklarierst eine Liste 
2. Du initalisiert die Liste
3. Du füllst die Liste mit Inhalt
4. Du liest Elemente aus der Liste

In deinem Beispiel ist 
2 = this.list = new Element[this.realCap];
und
3 = this.list[this.size] = element;

In deinem Hauptprogramm initalisiert du zwar deine Liste und dann benutzt du sie gleich, bevor sie mit Inhalt gefüllt wurde .

this.section = new Member[this.size]; initalisiert deine Liste, mehr NICHT.


----------



## boss3D (5. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Okay ... also wäre es das beste, 2 Getter für _overallIncome_ und _overallCosts_ zu schreiben? Ich probiere es mal aus ... 

*[EDIT]*
Bisschen was hat's gebracht. 2 der 4 Tests laufen schon mal fehlerfrei durch (die ohne Kostenberechnung):




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



Bei den anderen beiden (die MIT Kostenberechnung) habe ich immer noch NullPointerException. Also habe ich das Problem wohl nur "ausgelagert"?! Und wieso bekomme ich x-mal die Fehlerausgabe wegen dem Hinzufügen-Versuch der Section, wo ich das doch nur 1 Mal mache?


```
public double getOverallIncome() {
        for (int i = 0; i < section.length; i++) {
            this.overallIncome += this.section[i].getIncome();
        }
        return this.overallIncome;
    }
    
    public double getOverallCosts() {
        for (int i = 0; i < section.length; i++) {
            this.overallCosts += this.section[i].getCosts();
        }
        return this.overallCosts;
    }
```


----------



## -Phoenix- (5. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Ich glaub ich rede gerad irgendwie an dir vorbei 


```
1    public Section(int size) {
2       this.size = size;
3      this.allocation = 0;
4        this.section = new Member[this.size];
5        for (int i = 0; i < section.length; i++) {
6            this.overallIncome += this.section[i].getIncome(); // Zeile 18
7            this.overallCosts += this.section[i].getCosts(); // Zeile 19
8       }
9       this.sections = new ArrayList<Section>();
    }
```
4 -> Du erstellt ein Array mit der größe size.
5 -> section.lenght ist das gleiche wie this.size in diesem moment Wenn size > 0 dann gehe weiter
6 -> Du greist auf section[0] zu in section[0] steht null , null.getIncome() das kann nicht gutgehen
Du musst dein Memberarray erst mit Werten füllen bevor du die verwenden kannst oder du musst die verwendung an den Punkt verschieben wo Werte im Array sind.


----------



## boss3D (5. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Doch, ich verstehe schon, was du sagen willst. Ich verstehe nur nicht, wieso das Array die ganze Zeit über leer sein soll, wo ich doch in der TestKlasse 9 Mal (!) _addMember()_ aufrufe und dabei durch diese Zeile ...

```
this.section[this.allocation] = m;
```
... jedes Mal ein Member im Array landen müsste?!

Ich hab's jetzt so probiert; hat aber auch nichts gebracht:

```
public boolean addMember(Member m) {
        if (this.allocation < this.size) {
            this.section[this.allocation] = m;
            this.allocation++;
            for (int i = 0; i < section.length; i++) {
                this.overallIncome += this.section[i].getIncome();
                this.overallCosts += this.section[i].getCosts();
            }
            
        } else {
            System.out.println("Member can't be added! Section already full.");
            return false;
        }
        return true;
    }
```


----------



## -Phoenix- (5. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Debugger benutzen...........


ohne das im Konstruktor sollte es gehen

```
for (int i = 0; i < section.length; i++) {
            this.overallIncome += this.section[i].getIncome(); // Zeile 18
            this.overallCosts += this.section[i].getCosts(); // Zeile 19
        }
```
Wenn du eine neue Section erstellt wird der Konstruktor aufgerufen, im Konstruktor willst du jetzt die Kosten berrechnen, why?, du hast doch zu diesem Zeitpunkt noch keine Member in der Section das siehst du doch selber in deinem Code(SectionTest), du erstellst erst eine Section und erst später werden die Member in die Section eingefügt.<br>


----------



## boss3D (5. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

So hat's jetzt zu 75 % geklappt: ... 

```
public boolean addMember(Member m) {
        if (this.allocation < this.size) {
            this.section[this.allocation] = m;
            this.overallIncome += this.section[this.allocation].getIncome();
            this.overallCosts += this.section[this.allocation].getCosts();
            this.allocation++;
        } else {
            System.out.println("Member can't be added! Section already full.");
            return false;
        }
        return true;
    }
```
^^ Nur der _TestSectionAdd_ Testfall liefert noch einen Fehler, weil er sich _true_ erwartet, aber _false_ ist. Liegt aber höchstwahrscheinlich daran, dass ich mich einfach bei den Kosten verrechnet habe. Der andere, gleich-aufgebaute Testfall funktioniert ja auch. 

Taschenrechner her und dann kann ich das sicher korrigieren.

Nur die vielfache Ausgabe der Fehlermeldung beim Hinzufügen einer Section in eine bereits volle Section verstehe ich noch nicht. Ich habe ja jetzt gar keine Schleife mehr im Code?!

*[EDIT]*
Jetzt stimmen alle Tests.  Zwei Zeilen in _addSection()_ haben noch gefehlt:

```
public boolean addSection(Section section) {
        if (this.allocation < this.size) {
            this.sections.add(section);
            [COLOR=royalblue][B]this.overallIncome += section.overallIncome;
            this.overallCosts += section.overallCosts;[/B]            this.allocation++;
        } else {
            System.out.println("Sub-Section can't be added! Section already full.");
            return false;
        }
        return true;
    }
```



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        





			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.


----------



## -Phoenix- (10. Juni 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Antworten:




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



lg.


----------



## boss3D (9. Juli 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Ich versuche gerade, den Fragenkatalog für die Klausur durchzugehen und hänge gerade bei folgender Frage:


> [FONT=&quot]Was ist unter dynamischer Bindung zu verstehen und wo liegt hier der Vorteil gegenüber der statischen Bindung? Welche Rolle spielt hier das Prinzip Ersetzbarkeit?[/FONT]


Ich hätte jetzt erstmal gesagt ...

Dynamische Bindung: Zur Übersetzungszeit ist noch nicht bekannt, von welchem Typ ein Objekt sein wird bzw. zu welcher Klasse es gehört. Erst zur Laufzeit wird entschieden, welche Implementierung aufgrund eines Methodenaufrufs angewandt wird.

^^ Aber hat da wer eine wirklich vernünftige und vor allem ausführliche Antwort?! Auch in Bezug auf die beiden anderen Punkte (Vorteile gegenüber statischer Bindung und Ersetzbarkeit)?

[EDIT]
Als Vorteil würde mir noch einfallen, dass einer Variable bei dynamischer Bindung verschiedene Objekte (unterschiedlicher Klassen) zugewiesen werden können (falls man das so formulieren kann). Bsp.:

```
if (zufallszahl%2 == 0) { 
    koerper = new Kreis(i); 
} else { 
    koerper = new Quadrat(i); 
}
```



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.


----------



## Crysis nerd (10. Juli 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*



boss3D schrieb:


> Dynamische Bindung: Zur Übersetzungszeit ist noch nicht bekannt, von welchem Typ ein Objekt sein wird bzw. zu welcher Klasse es gehört. Erst zur Laufzeit wird entschieden, welche Implementierung aufgrund eines Methodenaufrufs angewandt wird.


Das ist erstmal eine richtige Beschreibung von dynamischer Bindung. Ein Vorteil wird hier auch schon "genannt", dass man mehr Freiheit zur Runtime hat. Was Ersetzbarkeit ist, weiß ich gerade nicht. Wahrscheinlich ist das wieder so ein schrecklich eingedeutschtes Wort, was im originalen englisch jedem Programmierer was sagen würde. 
Ich denke eine gute Antwort in diesem Fall wäre, wenn du die Konzepte der Objekt Orientierten Programmierung erwähnst. Wie der Wikipedia Artikel zu OOP sagt, ist Polymorphie ein Konzept von OOP.


> Polymorphie
> Fähigkeit eines Bezeichners, abhängig von seiner Verwendung unterschiedliche Datentypen anzunehmen. Verschiedene Objekte können auf die gleiche Nachricht unterschiedlich reagieren.


Und diese Polymorphie wird eben unter anderem durch dynamische Bindung realisiert. Zumindest die Polymorphie zur Runtime. Compiletime Polymorphie sollte durch Generics in Java (die kastrierte Variante von Templates) realisiert sein, aber hierbei bin ich mir nicht sicher.
Jedenfalls: Konzepte von OOP in der Klausur erwähnen is immer gut! 



boss3D schrieb:


> [EDIT]
> Als Vorteil würde mir noch einfallen, dass einer Variable bei dynamischer Bindung verschiedene Objekte (unterschiedlicher Klassen) zugewiesen werden können (falls man das so formulieren kann).



Das hat nichts mit dynamischer Bindung zu tun. Dynamische Bindung wird nur bei dem Aufrufen einer Methode angewendet! Was du beschriebst ist einfach implizites Casting zwischen Super- und abgeleiteten Klassen. Man kann auch ohne dynamisches Binden einer Variabel vom Typ SuperClass ein Objekt vom Typ DerivedClass zuweisen (obwohl es erstmal nicht so viel Sinn ergibt). 

Hoffe, dass es das ein wenig klarer gemacht hat.

LG 
Lukas


----------



## boss3D (10. Juli 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Ok, danke. Ich glaube, "Ersetzbarkeit" meint genau das, was ich ganz unten in meinem vorigen Posting mit dem Code und dem Bild angedeutet habe?! Aber K. A., der Lehrer ist Deutscher (in Österreich) und verwendet öfters mal "eingedeutschte" Wörter. Aus "Runtime" wird "Laufzeit", aus "Compile-time" wird "Übersetungszeit", usw. ... Egal. 

Das mit der Polymorphie habe ich meiner Antwort noch hinzugefügt.


----------



## Crysis nerd (10. Juli 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*



boss3D schrieb:


> Ok, danke. Ich glaube, "Ersetzbarkeit" meint genau das, was ich ganz unten in meinem vorigen Posting mit dem Code und dem Bild angedeutet habe?! Aber K. A., der Lehrer ist Deutscher (in Österreich) und verwendet öfters mal "eingedeutschte" Wörter. Aus "Runtime" wird "Laufzeit", aus "Compile-time" wird "Übersetungszeit", usw. ... Egal.
> 
> Das mit der Polymorphie habe ich meiner Antwort noch hinzugefügt.


 
Oh, ich dachte, es ginge um Uni/FH ^_^
Das mit eingedeutschten Wörtern kenn ich leider auch von Professoren, die statt Queue Schlange und statt Stack Keller verwenden. "Und jetzt returnieren wir diesen wert.." Ja es ist schrecklich -_-


----------



## boss3D (10. Juli 2013)

*AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...*

Ja, eh. FH in Österreich, aber ich nenne die Typen trotzdem "nur" Lehrer. Viele von denen haben ja nicht mal eine pädagogische Ausbildung ...

BTW: Wenn du's wirklich extrem haben willst --> "Modern Operating Systems" von Tanenbaum in der deutschen Version lesen.


----------

