# Einmalige Objekte



## Mido (15. Jun 2017)

kann jemanden mir bei dieser Aufgabe helfen ? 

Schreiben Sie eine Klasse LoneWolf, die die Attribute number vom Typ int und text vom Typ String besitzt und erweitern Sie diese wie folgt:

a)      Kapseln Sie die Attribute so, dass beide ausgelesen werden können. Das Attribut number darf nur auf Werte im Bereich [1,100] gesetzt werden. Das Attribut text darf nicht gesetzt werden können.

b)      Schreiben Sie einen Standardkonstruktor, der number auf den Wert -1 und text auf den Wert „I am so alone“ setzt.

c)       Sorgen Sie dafür, dass von dieser Klasse nur ein einziges Objekt erzeugt werden kann. Setzen Sie dafür die Sichtbarkeit des Konstruktors auf private, ergänzen sie ein privates statisches Attribut vom Typ LoneWolf und eine öffentliche statische Methode getInstance(), die das statische Attribut zurückliefert. Stellen Sie sicher, dass das Attribut instanziiert wird, bevor es von der Methode getInstance zurückgegeben wird. Stellen sie sicher, dass immer dasselbe Objekt zurückgegeben wird (kein neues).

d)      Schreiben sie eine ausführbare Klasse LoneTest in welcher sie das einzelne Objekt vom Typ LoneWolf verwenden. Setzten sie die Nummer des Wolfes auf 12 und lassen sie sich anschließend sowohl Nummer als auch Text auf der Konsole ausgeben. Erzeugen sie einen zweiten Wolf und lassen sie sich auch von diesem die Nummer ausgeben.


----------



## Robat (15. Jun 2017)

Und was ist dein Problem / deine Frage?


----------



## bs66 (15. Jun 2017)

Eine mögliche Lösung:
class LoneWolf

```
public class LoneWolf {
   
    private int number;
    private String text;
    private static LoneWolf lonewolf;
   
    static{
        lonewolf = new LoneWolf();
    }
   
   
    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        if(number > 0 && number < 101){
            this.number = number;
        }else{
            System.out.println("Bitte nur eine Zahl von 1 - 100 wählen!");
        }
    }

    public String getText() {
        return text;
    }

    private LoneWolf(){
        this.number = -1;
        this.text = "I am so alone";
    }
   
    public static LoneWolf getInstance(){
        return lonewolf;
    }

}
```

class LoneTest

```
public class LoneTest {

    public static void main(String[] args) {
       
        LoneWolf wolf = LoneWolf.getInstance();
        wolf.setNumber(12);
        System.out.println("Nummer des Wolfes: " + wolf.getNumber());
        System.out.println("Text: " + wolf.getText());
       
        LoneWolf wolf2 = LoneWolf.getInstance();
        System.out.println("Nummer des 2.Wolfes: " + wolf2.getNumber());

    }

}
```


----------



## Robat (15. Jun 2017)

@bs66 Was bringt ihm das jetzt? Eine fertig Lösung ohne Erklärung --> Lerneffekt gleich 0.


----------



## bs66 (15. Jun 2017)

@Robat Das kann ich nicht sagen. Ich habe selbst auch sehr viel aus fertigen Codes lernen können.


----------



## RalleYTN (15. Jun 2017)

Eine Klasse von der man nur ein einziges Objekt erzeugen kann wird meistens für diese ganzen Handler-, Manager-, Controller-Klassen verwendet wo man nicht möchte, dass ein Programmierer, der die API verwendet einfach so Mist bauen kann.

Um soetwas umzusetzen musst du der Klasse einfach einen privaten Konstruktor angeben und sicherstellen, dass es keinen anderen Konstruktor, der nicht private ist, existiert (Ich mache die Klasse meistens auch noch final) und dafür sorgen, dass einmalig eine Instanz der Klasse im Hintergrund erzeugt wird, die sich der Programmierer dann irgendwie holen kann.

Es gibt auch noch eine Version wo überhaupt garkein Objekt erzeugt wird und einfach alle Methoden innerhalb der Klasse statisch sind. Ein beispiel dafür wäre die Math Klasse.

Zu deiner Aufgabe:

```
public final class LoneWolf {

    private static final LoneWolf INSTANCE = new LoneWolf(); // Wird nur einmal ausgeführt

    private int number;
    private String text;

    private LoneWolf() {
   
        this.number = -1;
        this.text = "I am so alone";
    }

    public void setNumber(int number) {

        // Wenn number < 1 dann 1 andernfalls wenn number > 1000 dann 1000 andernfalls number
        this.number = number < 1 ? 1 : (number > 1000 ? 1000 : number);
    }

    public int getNumber() {

        return this.number;
    }

    public String getText() {

        return this.text;
    }

    public static LoneWolf getInstance() {

        return LoneWolf.INSTANCE;
    }
}
```


```
public class LoneTest {

    public static void main(String[] args) {

        LoneWolf wolf = LoneWolf.getInstance();
        wolf.setNumber(12);

        System.out.println(wolf.getNumber());
        System.out.println(wolf.getText());

        // Immernoch derselbe Wolf
        LoneWolf wolf2 = LoneWolf.getInstance();
        System.out.println(wolf.getNumber());
        System.out.println(wolf.getText());
    }
}
```


----------



## mrBrown (15. Jun 2017)

RalleYTN hat gesagt.:


> Eine Klasse von der man nur ein einziges Objekt erzeugen kann wird meistens für diese ganzen Handler-, Manager-, Controller-Klassen verwendet wo man nicht möchte, dass ein Programmierer, der die API verwendet einfach so Mist bauen kann.


Ist allerdings auch ein ziemliches Antipattern


----------



## RalleYTN (15. Jun 2017)

mrBrown hat gesagt.:


> Ist allerdings auch ein ziemliches Antipattern


Stimmt schon. Gibt jedoch APIs die sowas machen. JInput zum Beispiel mit der ControllerEnvironment Klasse.
¯\_(ツ)_/¯


----------



## Mido (15. Jun 2017)

Danke euch für die Hilfe
ich hab es auch so am Anfang geschrieben aber als ich get- und set- getroffen habe hab nicht weiter gemacht weil ich die nich verstanden habe

noch eine weitere frage hab ich und zwar über Kapselung , was bedeutet und wofür benutzt man es ?


----------



## Mido (15. Jun 2017)

Danke euch  @Robat , @bs66  , @RalleYTN


----------

