Vererbung equals-Methode bei Vererbung abstrakter Klassen

Knusper92

Mitglied
Hallo Leute 🙂,

Hab hier ein kleines Problem beim Verständnis einer Übungsaufgabe. Zunächst einmal die Aufgabenstellung:

Ich soll eine abstrakte Klasse mit Namen "Figuren3D" erzeugen. In dieser Klasse sollen sich die Attribute "Name" und "Gewicht" befinden, und die Methode "getVolumen". Zudem sollen die Methoden "equals" und "toString" überschrieben werden. Anschließend sollen die Klassen "Quader", "Kugel" und "Pyramide" von "Figuren3D" erben. Die Unterklassen erhalten zudem figurenspezifische Attribute (Länge, Breite, Höhe und Radius) und Konstruktoren.

Nun soll eine Testklasse "TestFiguren3D" geschrieben werden, welche drei verschiedene Figuren erstellt und als Array speichert. Die "equals"-Methode soll abschließend alle Figuren miteinander vergleichen und den Namen der Figur mit dem höchsten Gewicht ausgeben.

Ich poste zunächst mal den Code aller 5 Klassen:

Figuren3D

Java:
public abstract class Figuren3D{
    
//Attribute---------------------------------------------------------------------    
    String name;
    double gewicht;

//Methoden----------------------------------------------------------------------    
    public abstract double getVolumen();
    
    @Override 
    public boolean equals(Object figur){
        if (figur instanceof Figuren3D){
            Figuren3D f = (Figuren3D) figur;
            return (gewicht == f.gewicht);
        }
        return false;
    }
    
    @Override   
    public String toString(){
        return "Objekt: " + this.name + ", Gewicht: " + this.gewicht + ", Volumen: " + this.getVolumen();
    }
    
}

Quader

Java:
public class Quader extends Figuren3D {
    
//Attribute---------------------------------------------------------------------    
    double breite;
    double laenge;
    double hoehe;
    
//Methoden----------------------------------------------------------------------    
    @Override
    public double getVolumen(){
        return breite * laenge * hoehe;
    }

//Konstruktoren-----------------------------------------------------------------    
    public Quader(){
        name    = "standard";
        breite  = 
        laenge  =
        hoehe   = 1;
        gewicht = 1;
    }
    
    public Quader(String n, double b, double l, double h, double g){
        this.name    = n;
        this.breite  = b;
        this.laenge  = l;
        this.hoehe   = h;
        this.gewicht = g;
    }
    
}

Kugel

Java:
public class Kugel extends Figuren3D {
    
//Attribute---------------------------------------------------------------------
    double radius;
    
//Methoden----------------------------------------------------------------------
    @Override
    public double getVolumen(){
        return (4/3) * Math.PI * Math.pow(radius, 3);
    }
    
//Konstruktoren-----------------------------------------------------------------    
    public Kugel(){
        name    = "standard";
        radius  = 1;
        gewicht = 1; 
    }
    
    public Kugel(String n, double r, double g){
        this.name    = n;
        this.radius  = r;
        this.gewicht = g;
    }
        
}

Pyramide

Java:
public class Pyramide extends Figuren3D {
    
//Attribute---------------------------------------------------------------------
    double breite;
    double laenge;
    double hoehe;
    
//Methoden----------------------------------------------------------------------    
    @Override
    public double getVolumen(){
        return (1/3) * hoehe * breite * laenge;
    }
    
//Konstruktoren-----------------------------------------------------------------    
    public Pyramide(){
        name    = "standard";
        breite  = 
        laenge  =
        hoehe   = 1;
        gewicht = 1;
    }
    
    public Pyramide(String n, double b, double l, double h, double g){
        this.name    = n;
        this.breite  = b;
        this.laenge  = l;
        this.hoehe   = h;
        this.gewicht = g;
    }
}

Java:
public class TestFiguren3D {
    
    public static void main(String[] args) {
        
        Figuren3D[] f = new Figuren3D[3];
        
        f[0] = new Quader("Quader_1", 5.5, 6.7, 2.1, 36.2);
        f[1] = new Kugel("Kugel_1", 4.5, 66.2);
        f[2] = new Pyramide("Pyramide_1", 2.3, 3.7, 6.3, 36.2);
        
        System.out.println(f[0]);
        System.out.println(f[1]);
        System.out.println(f[2]);
        
        if(f[0].equals(f[1])) { 
                System.out.println("Figur 1 und 2 sind gleich!");
        } 
        if(f[0].equals(f[2])) { 
                System.out.println("Figur 1 und 3 sind gleich!");
        }
        if(f[1].equals(f[2])) { 
                System.out.println("Figur 2 und 3 sind gleich!");
        }
        if(!(f[0].equals(f[1]) || f[0].equals(f[2]) || f[1].equals(f[2])))
            System.out.println("Alle Figuren haben unterschiedliche Gewichte.");
    }
}

Ich verstehe nicht, warum in der Klasse "Figuren3D" bei dem Überschreiben der equals-Methode hinter dem
Java:
return (gewicht == f.gewicht);
noch ein
Java:
return false;

Was macht das return false?

Danke schon mal für die Antworten und ich hoffe, dass das Beantworten der Frage nicht zu viel Zeit in anspruch nimmt! 😉
 
Java:
        if (figur instanceof Figuren3D){
            Figuren3D f = (Figuren3D) figur;
            return (gewicht == f.gewicht);
        }
        return false;
Verstehst Du den if-Zweig? Wann ist instanceof true? Und unter welchen Umständen ist es false? Wenn es false ist, wird der if-Zweig ja nicht betreten. Warum ist es dann sinnvoll, false zu returnen?

P.S. Der Parametername figur ist sehr unglücklich, weil er impliziert, dass immer eine Figur übergeben wird. Dem ist aber nicht so. equals kann mit allem als Parameter aufgerufen werden. Nenne den Parameter darum besser obj oder so.

P.P.S. Abgesehen davon ist es in nicht finalen Klassen eine ziemlich schlechte Idee, mit instanceof zu prüfen. Aber in die Tiefen des equals-Kontrakts soll hier ja wohl nicht eingestiegen werden...
 
Zuletzt bearbeitet von einem Moderator:
ich denke für deine frage muss man sich ja nur die erste klasse ansehen. du hast da ne methode
Code:
 public boolean equals(Object figur){
die einen boolean zurückgibt (true oder false). mit return wird ja in diesem fall true oder false zurückgegeben.

Java:
if (figur instanceof Figuren3D){
            Figuren3D f = (Figuren3D) figur;
            return (gewicht == f.gewicht);
        }
das return dort wird ja nur zurückgegeben falls instanceof Figuren3d true ist. falls es nun keine instance ist, muss ja dennoch irgendwas zurückgegeben werden. und deswegen steht da
Code:
return false;

anmerkung: du solltest wissen dass wenn das hier passiert
Code:
 return (gewicht == f.gewicht);
dass der -direkt- aus der methode "rausspringt", also den rest nicht mehr macht egal was noch kommt. d.h. wenn instanceof Figuren3d true ist, kommt das programm niemals zu
Code:
 return false;
 
Zuletzt bearbeitet:
Wow danke für die schnellen Antworten! 🙂

@nillehammer

Ja den verstehe ich. Aufgrund der uns gegebenen Aufgabe ist mir auch gar nicht in den Sinn gekommen, dass es auch sein könnte, dass die geprüfte Klasse auch was anderes sein könnte als ne Unterklasse von "Figuren3D" 😀 Jetzt ergibt alles Sinn^^

Keine Ahnung unser Prof hat uns halt erzählt, dass man damit schaut, ob es überhaupt Sinn macht die Klassen per equal zu vergleichen.

@vimar

Ahh alles klar das war nochmal wichtig mit dem rauspringen 😉 Danke!
 
Keine Ahnung unser Prof hat uns halt erzählt, dass man damit schaut, ob es überhaupt Sinn macht die Klassen per equal zu vergleichen.
Dass stimmt auch. Wenn die Objekte nicht vom selben Typ sind können sie auch nicht gleich sein.

Dass Problem: wenn die Objekte vom selben abstrakten Typ sind kann können sie trotzdem nicht vergleichbar sein: Äpfel kann man eben nicht mit Birnen vergleichen, obwohl beides Obst ist. Ganau dasswürde
Code:
equals()
in einer abstrakten Klasse tun....

bye
TT
 
Keine Ahnung unser Prof hat uns halt erzählt, dass man damit schaut, ob es überhaupt Sinn macht die Klassen per equal zu vergleichen.
Das stimmt, mit instanceof kann man verhindern, dass Äpfel mit Birnen verglichen werden. Praktischerweise wird auch gleich der null-Fall mit geprüft. Aber er ist zu lachs, da er eben auch für Unterklassen true zurück liefert. Bei nicht finalen Klassen sieht der erste Teile der equals-Methode immer so aus:
Java:
// Abkürzung, wenn identisch:
if(this== obj) {
  return true;
}
// wenn null oder nicht vergleichbar, Klassenvergleich statt instanceof
if(obj == null || obj.getClass() != this.getClass) {
  return false;
}
// jetzt der ganze Fachkram
...
Falls Du nicht nur den Schein haben willst, sondern ernsthaft mit Java arbeiten willst, empfehle ich folgenden Link: AngelikaLanger.com - Implementing the equals() Method - Part 2 - Angelika Langer Training/Consulting

Auch ihre anderen Artikel sind sehr lesenswert.
 
Zuletzt bearbeitet von einem Moderator:
Timothy Truckle hat gesagt.:
Dass Problem: wenn die Objekte vom selben abstrakten Typ sind kann können sie trotzdem nicht vergleichbar sein: Äpfel kann man eben nicht mit Birnen vergleichen, obwohl beides Obst ist. Ganau dasswürde equals() in einer abstrakten Klasse tun....
Sehr gut auf den Punkt gebracht!
 
Jo denke ich hab das Problem verstanden! Den Link habe ich mir gespeichert und werde mal ein bisschen lesen wenn ich mit meinen Prüfungen durch bin. Java soll nen neues Hobby von mir werden, will vllt so nen paar Programme oder Apps für mein Smartphone schreiben aber will das schon vernünftig lernen werd mir die Tipps zu Herzen nehmen!

So danke noch mal und schönen Abend 😉
 
Java soll nen neues Hobby von mir werden,
Herzlichen Glückwunsch! Dann hast Du Dich für eine lange Periode des Frusts entschieden 😉 Ich hab glaub ich locker nen Jahr (wenn nicht sogar mehr) Java "programmiert", bis ich so langsam verstanden habe, was ich da eigentlich mache, mit dem entsprechenden Frustfaktor natürlich :autsch:

Aber tröste Dich, danach kann es durchaus Spaß machen.:toll:
 

Zurück
Oben