# Abstrakte Klasse mit Interfaces



## Marco_D (15. Nov 2019)

Hallo ich bin neu hier und brauche Hilfe bei einer Aufgabe. Da ich ein blutiger Java Anfänger bin, wäre ich euch echt dankbar wenn ihr mir helfen könntet Lösungsansätze zu definieren. Anbei noch das dazugehörige UML-Diagram. Die Aufgabe lautet wie folgt: 

Erstellen Sie zunächst eine abstrakte Klasse Dog, ein Interface BarkBehavior und ein Interface RunningBehavior im Package h3 aus Aufgabe H1. Die abstrakte Klasse Dog verfügter zwei Attribute, die das Bell- bzw. Laufverhalten des Hundes beschreiben, und zwei Methoden, die das Bell- bzw. Laufverhalten setzen. Außerdem besitzt sie zwei Methoden run() und bark(), dessen Ru ̈ckgabetyp String ist, und welche schließlich dem Nutzer der Implementierung die Mo ̈glichkeit bieten, das Verhalten zu simulieren. Ihre Aufgabe ist es, die Attribute und Methoden so zu implementieren, dass fu ̈r von Dog erbende Klassen unterschiedliche Verhalten beschrieben werden können, und die konkreten Ver- halten u ̈ber run() und bark() der Implementierungen der Interfaces BarkBehavior undRunningBehavior zurückgeben werden. 









						Bilder-Upload - Kostenlos Fotos hochladen und ins Netz stellen
					

Kostenlos Bilder hochladen. Bilder Upload ohne Anmeldung




					www.bilder-upload.eu


----------



## Robat (15. Nov 2019)

Hast du auch eine konkrete Frage dazu? Was hast du denn bis her? Das UML Diagramm inkl. Aufgabe kann man ja fast Wort für Wort runtertippen


----------



## mihe7 (15. Nov 2019)

Hallo erstmal.



Marco_D hat gesagt.:


> wenn ihr mir helfen könntet Lösungsansätze zu definieren.


Das würden hier sicher viele gerne tun. Dazu müsste man wissen, wo es hakt und was Du ggf. schon als Code hast. Das Problem ist, dass diese Aufgaben derart detailliert beschrieben sind, dass sie 1:1 in Code übersetzt werden können.

EDIT: @Robat war schneller.


----------



## kneitzel (15. Nov 2019)

Ansonsten evtl. Head First Design Patterns (oder die Übersetzung: Entwurfsmuster von Kopf bis Fuß) lesen. Das erste Kapitel beschreibt dies sehr ausführlich von Anfang bis Ende - das Strategy Pattern um das es hier schlicht geht.


----------



## Marco_D (15. Nov 2019)

Danke für die schnellen Antworten. Ich habe mir jetzt erstmal Videos bezüglich des Strategy Pattern angeschaut. Ich lese jetzt das von @JustNobody empfohlene Kapitel durch. Bei einem Video welches eigentlich sehr gut war, wurden jedoch nochmal extra Klassen erstellt die vom Interface "implements", da seine zwei Objekte (Zyklop und Drache) jeweils eine Unterschiedliche AngriffsArt haben. Die haben jedoch die gleiche Lauf und Schwimmeigenschaft. Wenn ich jetzt jedoch ebenfalls so vorgehe wie er es im Video tut dann hätte ich ja viel zu viele Klassen. Ich soll ja keine zusätzlichen Klassen erstellen die von den Interfaces Implements, sondern alles in die Interfaces selbst schreiben


----------



## mihe7 (15. Nov 2019)

Marco_D hat gesagt.:


> Ich soll ja keine zusätzlichen Klassen erstellen die von den Interfaces Implements, sondern alles in die Interfaces selbst schreiben


In Deinem UML-Diagramm ist z. B. NoBarking eine Klasse, die das Interface BarkBehavior implementiert. Dadurch, dass NoBarking das Interface BarkBehavior implementiert, kann ein NoBarking-Objekt so verwendet werden, wie in BarkBehavior angegeben.


----------



## Marco_D (15. Nov 2019)

Ah also bedeutet das, dass ich 3 Klassen habe, die vom Interface BarkBehavior implementieren und 3 Klassen von RunBehavior.
In der Aufgabenstellung steht ja:
Die abstrakte Klasse Dog verfügt über zwei Attribute, die das Bell- bzw. Laufverhalten des Hundes beschreiben:


```
BarkBehavior barkBehavior;
RunningBehavior runBehavior;
```

Außerdem soll die Klasse Dog über zwei Methoden verfügen, die das Lauf bzw. Bellverhalten setzen. Ich weiß jedoch nicht wie ich das in Code umsetzten kann.


----------



## kneitzel (15. Nov 2019)

Wenn Du das Kapitel in dem Buch liest, dann siehst Du die Implementierung da doch. Also lies doch erst einmal das Kapitel im Buch in Ruhe zu Ende und wenn dann noch Fragen offen sind, dann kannst Du gerne erneut fragen.

Wobei Methoden, die eine Instanzvariable setzen, generell Setter heißen und eigentlich immer gleich aussehen. Also wenn Du eine Variable barkBehaviour vom Typ BarkBehaviour hast, dann kannst Du einen Setter schreiben:

```
public void setBarkBehaviour(final BarkBehaviour barkBehaviour) {
  this.barkBehaviour = barkBehaviour;
}
```


----------



## mihe7 (15. Nov 2019)

Marco_D hat gesagt.:


> Ah also bedeutet das, dass ich 3 Klassen habe, die vom Interface BarkBehavior implementieren und 3 Klassen von RunBehavior.


Exakt - wenn Du denn diese Klassen implementieren würdest. Das scheint mir bei der Aufgabe aber nicht gefordert und die dort genannten Klassen sollen wohl nur der Veranschaulichung dienen.



Marco_D hat gesagt.:


> Die abstrakte Klasse Dog verfügt über zwei Attribute, die das Bell- bzw. Laufverhalten des Hundes beschreiben:


Richtig und wie das Setzen funktioniert, hat Dir @JustNobody schon gezeigt


----------



## Marco_D (15. Nov 2019)

```
public void setBarkBehavior() {
        barkBehavior = new noBark();
        barkBehavior = new quietBark();
        barkBehavior = new loudBark();
        
 
}
    public void setRunningBehavior() {
        runningBehavior = new noRunning();
        runningBehavior = new slowRunning();
        runningBehavior = new fastRunning();
        
 
}
```

Das ist der Code der Klasse Dog für das setzen des Verhaltens. Wenn ich jetzt eine neue Klasse erstelle wie z.B.: Schäferhund dann lasse ich ihn von Dog erben (extends). Wie kann er dann z.B. das Laufverhalten setzen. 


```
Schäferhund Wolfgang = new noRunning();

// oder

Dog Wolfgang = new Schäferhund
Wolfgang.setRunningBehavior = new noRunning();
```


----------



## Marco_D (15. Nov 2019)

JustNobody hat gesagt.:


> Wenn Du das Kapitel in dem Buch liest, dann siehst Du die Implementierung da doch. Also lies doch erst einmal das Kapitel im Buch in Ruhe zu Ende und wenn dann noch Fragen offen sind, dann kannst Du gerne erneut fragen.
> 
> Wobei Methoden, die eine Instanzvariable setzen, generell Setter heißen und eigentlich immer gleich aussehen. Also wenn Du eine Variable barkBehaviour vom Typ BarkBehaviour hast, dann kannst Du einen Setter schreiben:
> 
> ...



ah sorry hab die Nachricht nicht gesehen. Danke


----------



## kneitzel (15. Nov 2019)

Marco_D hat gesagt.:


> ```
> public void setBarkBehavior() {
> barkBehavior = new noBark();
> barkBehavior = new quietBark();
> ...


Dazu einfach nur einmal die kurze Frage:
Was genau würde dieser Code machen? Was ist nach einem Aufruf von setBarkBehaviour der Inhalt von barkBehavior?


----------



## Marco_D (15. Nov 2019)

Stimmt, hier wäre dann doch nach dem Aufruf der Methode setBarkBehavior() der Inhalt von bark Behavior, sowohl noBark, quietBark als auch loudBark ?! Also müsste dann mein Code wie folgt aussehen:



```
public void setNoBark() {
        barkBehavior = new noBark();
}

    public void setQuietBark() {
        barkBehavior = new quietBark();
}

    public void setLoudBark() {
        barkBehavior = new loudBark();
}

//In der Klasse Schäferhund, die von Dog erbt das bellen auf laut setzen:

Schaeferhund Manny = new Dog;
Manny.setLoudBark();
```


----------



## Marco_D (15. Nov 2019)

Marco_D hat gesagt.:


> Stimmt, hier wäre dann doch nach dem Aufruf der Methode setBarkBehavior() der Inhalt von bark Behavior, sowohl noBark, quietBark als auch loudBark ?! Also müsste dann mein Code wie folgt aussehen:
> 
> 
> 
> ...



Aber die Sache ist ja die, dass ich nur zwei Methoden schreiben soll. Eine um das Bellverhalten und eine um das Laufverhalten zu setzen


----------



## kneitzel (15. Nov 2019)

Marco_D hat gesagt.:


> Stimmt, hier wäre dann doch nach dem Aufruf der Methode setBarkBehavior() der Inhalt von bark Behavior, sowohl noBark, quietBark als auch loudBark ?!



Nein, eine Variable hat immer genau einen Wert. Wenn die Variable nur deklariert aber nicht initialisiert wurde, dann kann der Wert nicht definiert sein (Und der Compiler meckert, wenn Du auf die Variable vorher lesend zugreifen willst), aber eine Variable kann nicht mehrere Werte haben.


```
int i;
i = 1;
i = 2;
i = 3;
```
i ist dann natürlich 3. Dass es vorher 1 oder 2 war, ist da egal. Also kann man das gleich weglassen.

Also worauf ich hinaus wollte: Betrachte Deinen Code und erkenne, was Sinn macht oder eben keinen Sinn macht. Mehrere Zuweisungen wie z.B. in dem ganz einfachen Beispiel jetzt mit i machen so in der Regel keinen Sinn.



Marco_D hat gesagt.:


> Also müsste dann mein Code wie folgt aussehen:
> 
> 
> 
> ...



Das wäre natürlich ein valider Code. Aber macht das Sinn?
Sinn dieses Pattern ist doch eben, dass es einem "Hund" egal ist, was es für ein Bellen gibt und es kann jederzeit neue Implementationen für das Bellen geben ohne dass eben die Klasse Hund geändert werden muss!

Und bezüglich des Schaeferhunds Manny:
a) Variablen klein schreiben => manny
b) Konstruktoren wollen mit Klammer aufgerufen werden: => new Dog();
(Wobei Dog laut Aufgabe abstrakt sein soll, d.h. new Dog() funktioniert nicht!)
c) Schaeferhund erbt von Dog. Ein Schaeferhund ist damit ein Dog. Ein Dog ist aber kein Schaeferhund! Damit kann man kein new Dog() zu einem Schaeferhund zuweisen. Umgedreht ginge es: Dog manny = new Schaeferhund();


----------



## mihe7 (15. Nov 2019)

JustNobody hat gesagt.:


> Sinn dieses Pattern ist doch eben, dass es einem "Hund" egal ist, was es für ein Bellen gibt und es kann jederzeit neue Implementationen für das Bellen geben ohne dass eben die Klasse Hund geändert werden muss!


@Marco_D Genau das ist der Punkt. Du kannst das leise Bellen z. B. mit `System.out.println("bark");` (das laute natürlich dann mit "BARK"  ) implementieren. Eine andere Implementierung könnte einen Sound abspielen. Das alles muss das Dog-Objekt nicht interessieren.


----------

