# Abstrakte Klassen



## JavaIsTheBest (1. Jun 2016)

Hallo,
diese Aufgabe habe ich schonmal versucht, hatte dabei aber große Schwierigkeiten. Deswegen der 2. Versuch.

Meine erste Frage lautet. Ist mit "
_x.equals(y) soll genau dann true liefern, wenn y ebenfalls ein Ausdruck
ist, der strukturell und inhaltlich mit x übereinstimmt." _
folgendes gemeint?

(1+3)*(5-6)== (3+1)*(5-6) --> false
(1+2)*(3-4)== (1+2)*(3-4) --> true


----------



## Joose (1. Jun 2016)

Klingt gut ja!


----------



## JavaIsTheBest (1. Jun 2016)

Was spricht nochmal dagegen, die Methode equals so, wie ich zu implementieren, anstatt so, wie im Klassendiagramm?


```
public boolean equals(Const c){
        if(this.equals(c)){
            return true;
        }
        return false;
    }
```


----------



## InfectedBytes (1. Jun 2016)

du hast eine endlos rekursion gebaut. Deine equals funktion ruft sich selbst auf, wodurch der gleiche code nochmal ausgeführt wird und sich die equals methode wieder selbst aufruft und wieder und wieder.....


----------



## JavaIsTheBest (2. Jun 2016)

1. In der Klasse Const ist als Parameter bei der equals Methode ein Object angegeben. Ich habe das so gemacht. Spricht etwas dagegen?


```
public boolean equals(Const c){
        return this.value==c.value;
    }
```

2. Warum wird in der combine Methode ein double Wert als Parameter erwartet? Ich hätte eher gesagt, der Parameter müsste vom Typ Expr sein.

3. Mir ist noch nicht der Unterschied zwischen der combine und compute Methode klar.


----------



## mrBrown (2. Jun 2016)

JavaIsTheBest hat gesagt.:


> 1. In der Klasse Const ist als Parameter bei der equals Methode ein Object angegeben. Ich habe das so gemacht. Spricht etwas dagegen?
> 
> 
> ```
> ...



Ja, damit überschreibst du nicht equals(Object o), sondern erstellst eine weitere. Deine würde in den meisten Fällen nicht aufgerufen, sondern die #equals(Object o), die du nicht überschrieben hast.
Deshalb: An überschriebenes immer `[USER=48687]@Override[/USER]` an überschriebenes, dann gibts Compilerfehler wenns nicht passt.



JavaIsTheBest hat gesagt.:


> 2. Warum wird in der combine Methode ein double Wert als Parameter erwartet? Ich hätte eher gesagt, der Parameter müsste vom Typ Expr sein.
> 
> 3. Mir ist noch nicht der Unterschied zwischen der combine und compute Methode klar.



compute versteckt den Aufruf der rechten und linken Teile vor den Subklassen, die Subklassen müssen dann nur noch ein combine die wirkliche Rechnung mit den beiden Werten implementieren, und sich nicht mehr darum kümmern, an die Werte zu kommen.
Das verhindert duplizierten Code (das Berechnen des rechten/linken, was sonst jede Subklasse machen müsse) und macht den Code auch übersichtlicher, weil man nur noch diese eine Rechenoperation mit 2 Werten implementieren muss.

Also, compute ist die öffentliche API, und mit combine wird den Subklassen die Implementation von  compute zugunsten von was übersichtlicherem erspart.

Man könnte sich Zombie sparen, und die Subklassen compute implementieren lassen, hat dann aber doppelten Code, und muss sich selbst um die richtigen Aufrufe kümmern. 
Das mag bei diesen kleinen Beispielen manchmal nicht so offensichtlich sein, aber bei größeren/komplexeren Methoden sieht man dann recht gut den Vorteil, die Subklassen nur sehr kleine Methoden überschrieben zu lassen, aber den ganzen Code drum herum in den Oberklassen zu kapseln.


----------



## JStein52 (2. Jun 2016)

mrBrown hat gesagt.:


> Ja, damit überschreibst du nicht equals(Object o), sondern erstellst eine weitere. Deine würde in den meisten Fällen nicht aufgerufen


Du hast ja recht mit dem was du schreibst aber will sie denn equals(Object o) überschreiben ?  Für Const-Objekte würde ihre equals aufgerufen und das will sie doch.


----------



## mrBrown (2. Jun 2016)

JStein52 hat gesagt.:


> Du hast ja recht mit dem was du schreibst aber will sie denn equals(Object o) überschreiben ?  Für Const-Objekte würde ihre equals aufgerufen und das will sie doch.



Nur, wenn man den Aufruf von #equals selbst schreibt. Alle anderen Aufrufe, zB in Listen, benutzen die nicht überschriebene #equals. 
Wenn man doch spezielle equals für einzelne Typen braucht, würde ich sie anders benenne, das führt sonst nur zu Verwirrung.


----------



## JStein52 (2. Jun 2016)

mrBrown hat gesagt.:


> Wenn man doch spezielle equals für einzelne Typen braucht, würde ich sie anders benennen


Ja, ok. Das stimmt.


----------



## JavaIsTheBest (2. Jun 2016)

Aber, wäre meine Lösung laut Aufgabenstellung auch richtig (bezogen auf die equals Methode)? Und ich überschreibe, doch nicht die Methode sondern überlade sie?


----------



## mrBrown (2. Jun 2016)

Ja, du überlädst sie, überschreibst sie aber nicht. Deshalb würde ich es als nicht richtige Lösung ansehen.


----------



## JavaIsTheBest (2. Jun 2016)

Wie, JStein52 schon gesagt hat, funktioniert die Methode. Nirgendwo in der Aufgabenstellung steht aber, dass die equals Methode überschrieben wrden muss. Also, müsste die Methode doch richtig sein? Oder irre ich mich?


----------



## mrBrown (2. Jun 2016)

Im Klassendiagramm ist es als #equals(Object other) angegeben


----------



## JStein52 (2. Jun 2016)

Das wollte ich eigentlich am Anfang schon fragen: ist das Klassendiagramm Teil der Aufgabenstellung oder ist das deine Lösung ?


----------



## mrBrown (2. Jun 2016)

Und auch wenn Überschreiben nicht explizit gefordert ist und Typen nicht explizit angegeben sind: wenn die Methoden gleich heißen, würde ich immer davon ausgehen, dass die Methode aus der Superklasse gemeint ist


----------



## JavaIsTheBest (2. Jun 2016)

JStein52 hat gesagt.:


> Das wollte ich eigentlich am Anfang schon fragen: ist das Klassendiagramm Teil der Aufgabenstellung oder ist das deine Lösung ?



Eigentlich Teil der Aufgabenstellung.


----------



## JStein52 (2. Jun 2016)

Ok, war nur ne Frage falls du mal wieder sowas postest


----------



## JavaIsTheBest (2. Jun 2016)

Warum ist es beim ersten Beispiel eine Endlosrekursion und beim zweiten Beispiel nicht?

Bsp 1:


```
public boolean equals(Const c){
            if(this.equals(c)){
                return true;
            }
            return false;
        }
```

Bsp 2: (Hier wird die equals Methode auch innerhalb der equals Methode aufgerufen)


```
public boolean equals (Object other) {
if (!(other instanceof Bin)) return false;
Bin that = (Bin)other;
return this.oper().equals(that.oper())
&& this.left.equals(that.left)
&& this.right.equals(that.right);
}
```


----------



## mrBrown (2. Jun 2016)

beim ersten rufst du das selbe `equals` auf (`this.euqals` ruft `this.equals` auf, das ruft wieder `this.equals` auf, usw)

beim zweiten ruft `this.equals` `this.left.equals` auf, was eine andere Methode ist (da von `left`, nicht von `this`)


----------

