Abstrakte Klasse mit Interfaces

Marco_D

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

 

Robat

Top Contributor
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

Top Contributor
Hallo erstmal.

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

kneitzel

Gast
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

Mitglied
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

Top Contributor
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

Mitglied
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:

Java:
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.
 
K

kneitzel

Gast
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:
Code:
public void setBarkBehaviour(final BarkBehaviour barkBehaviour) {
  this.barkBehaviour = barkBehaviour;
}
 

mihe7

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

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

Mitglied
Java:
    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.

Java:
Schäferhund Wolfgang = new noRunning();

// oder

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

Marco_D

Mitglied
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:
Code:
public void setBarkBehaviour(final BarkBehaviour barkBehaviour) {
  this.barkBehaviour = barkBehaviour;
}

ah sorry hab die Nachricht nicht gesehen. Danke
 
K

kneitzel

Gast
Java:
    public void setBarkBehavior() {
        barkBehavior = new noBark();
        barkBehavior = new quietBark();
        barkBehavior = new loudBark();
}
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

Mitglied
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:


Code:
    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

Mitglied
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:


Code:
    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();

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

kneitzel

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

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

Also müsste dann mein Code wie folgt aussehen:


Code:
    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();

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

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

Neue Themen


Oben