Vererbung mit toString()

excuseme

Mitglied
Hallo!
Ich habe erst einmal eine Klasse Ausweis mit den zugehörigen Attributen erstellt und einer Methode toString(), die aus der Main Klasse die Namen etc. bekommt. Stimmt dieser toString so und ist diese Methode dafür da, das die Ausgabe in der Main Klasse nicht in so einem komischen Hashcode erfolgt? Und was genau macht die Methode print, mit this.toString(). Das @Override wurde mir gesagt ist notwendig, aber ich verstehe nicht genau den Sinn dahinter.
Java:
public class Ausweis {
    private String vorname;
    private String nachname;
    private String geschlecht;

    public Ausweis(String vorname, String nachname, String geschlecht) {
   
    this.vorname = vorname;
    this.nachname = nachname;
    this.geschlecht = geschlecht;
    }
  
   //getter und setter

    public static void main(String[] args) {
        Ausweis ausweis = new Ausweis("Harry", "Derp", "M");
        System.out.println(ausweis);
    }
    public void print() {
        System.out.println(this.toString());
    }
    @Override
    public String toString() {
    return "Vorname: " + vorname + "\nNachname: " + nachname + "\nGeschlecht: " +geschlecht;
    }   
}

Nun möchte ich die Attribute an eine andere Klasse vererben.

Java:
public class Studentenausweis extends Ausweis {
   
    int matrikelnummer;
   
public Studentenausweis(String vorname, String nachname, String geschlecht, int matrikelnummer) {
    
     super(vorname, nachname, geschlecht);
     this.matrikelnummer = matrikelnummer;
    
}
    
     public int getMatrikelnummer() {
         return matrikelnummer;
     }
     public void setMatrikelnummer(int matrikelnummer) {
         this.matrikelnummer = matrikelnummer;
     }
    
     public static void main(String[] args) {
         Studentenausweis s = new Studentenausweis("Harry", "Derp", "M", 501421);
         System.out.println(s);
     }
     public void print() {
        System.out.println(this.toString());
     }
     @Override
     public String toString(){
         return "Vorname:" + getVorname() + "\nNachname:" + getNachname() + "\nGeschlecht:" + getGeschlecht() + "\nMatrikelnummer: " + matrikelnummer;
     }
}
Meine Frage hierzu ist, ob ich in der Main Klasse den Vornamen, Nachnamen und das geschlecht aus der Superklasse einfügen kann, ohne es selber nochmal ausfüllen zu müssen? Also so, dass ich nur die Matrikelnummer ergänzen muss. Und muss ich in der toString() Methode mit Gettern arbeiten?

Liebe Grüße!
 
... toString so und ist diese Methode dafür da, das die Ausgabe in der Main Klasse nicht in so einem komischen Hashcode erfolgt?
Ja.
Und was genau macht die Methode print, mit this.toString()
Ich nehme an, du meinst System.out.println()? Die ruft intern die "toString()" Methode auf...
Edit: OK, nicht aufgepasst: Die Methode "print" ruft natürlich zuerst die o.g. Methode auf. In der "main" müsstet du also nur noch schreiben ausweis.print()

Das @Override wurde mir gesagt ist notwendig, aber ich verstehe nicht genau den Sinn dahinter.
Es ist nicht zwingend notwendig, aber es verhindert Fehler, darum sollte man es sich angewöhnen, wenn man bei einer abgeleiteten Klasse Methoden überschreiben möchte. Außerdem zeigt es demjenigen, der deinen Code liest (oder auch dir selbst, nach einigen Wochen) an, dass du hier etwas überschreiben möchtest.

Würdest du z.B. beim Überschreiben von "toString()" versehentlich "ToString()" schreiben, dann würdest du eine Fehlermeldung vom Compiler erhalten, dass du nicht überschreibst.
 
Meine Frage hierzu ist, ob ich in der Main Klasse den Vornamen, Nachnamen und das geschlecht aus der Superklasse einfügen kann, ohne es selber nochmal ausfüllen zu müssen?
Die Frage verstehe ich nicht ganz. In einem Programm sollte es nur eine Klasse geben, die eine main()-Methode hat, insofern solltest du in beiden Klassen auf diese Methode verzichten und diese in eine andere Klasse verlagern.
 
Das meiste hat @temi schon beantwortet. Trotzdem noch mein Senf dazu:

die aus der Main Klasse
Die Bezeichnung "Main Klasse" ist etwas irreführend. Du hast zwei Klassen, jeweils mit main-Methode und mit "Main Klasse" meinst Du wahrscheinlich die Klasse, deren main-Methode beim Aufruf Deiner Anwendung verwendet wird.

Stimmt dieser toString so und ist diese Methode dafür da, das die Ausgabe in der Main Klasse nicht in so einem komischen Hashcode erfolgt?
Ob die Methode so "stimmt", können wir nicht beurteilen. Du hast toString richtig überschrieben, aber ob das Ergebnis Deinen Anforderungen genügt, musst Du selber wissen 🙂

Die Methode toString ist in Klasse Object (von der alle Klassen direkt oder indirekt automatisch erben) definiert und dient dazu, eine Darstellung des Objekts in Textform zu erhalten. In Object wird der Klassenname gefolgt von @ und dem Hashcode als Hex-String zurückgeben. Wem das nicht gefällt, kann die Methode überschreiben.

Dass die Methode bei der Ausgabe über System.out automatisch aufgerufen wird, ist übrigens keine Besonderheit der Sprache. System.out ist ein PrintWriter-Objekt. Diese Klasse defineirt die Methoden print, println und printf (auch) für Object und ruft dort - über den Umweg über String.valueOf(Object) - ganz profan Object#toString() auf.

Meine Frage hierzu ist, ob ich in der Main Klasse den Vornamen, Nachnamen und das geschlecht aus der Superklasse einfügen kann, ohne es selber nochmal ausfüllen zu müssen?
Meine Vermutung: es geht hier um die Klasse Studentenausweis. Und die Frage ist, ob Du in toString() den gleichen Code wie in der Superklasse Ausweis nochmal schreiben musst.

Nein, musst Du nicht. Mit dem Schlüsselwort super kann auf Variablen, Konstruktoren und Methoden der Superklasse zugegriffen werden:
Java:
public String toString() {
    return super.toString() + "\nMatrikelnummer: " + matrikelnummer;
}

Und muss ich in der toString() Methode mit Gettern arbeiten?
Die toString-Methode ist nichts spezielles. Ob Du ganz allgemein in Methoden mit Gettern arbeiten musst, hängt ebenso allgemein davon ab, ob Du direkten Zugriff auf die entsprechenden Variablen hast.

In Deinem Beispiel war es möglich, die Matrikelnummer ohne Getter auszugeben - Zugriff ist ja da. In Klasse Ausweis sind die Felder dagegen private, d. h. nur in der Klasse Ausweis hast Du auf diese Felder Zugriff. Außerhalb der Klasse ist der Zugriff nur über entsprechende Methoden (Getter) möglich.

Wären die Felder nicht private sondern nur protected, dann könntest Du auf diese auch in Subklassen direkt zugreifen. Davon würde ich aber im Allgemeinen abraten, weil das leicht zu fragilem Code führen kann. Grundregel: Zugriff möglichst restriktiv handhaben - Instanzvariablen sind private.
 
Das @Override wurde mir gesagt ist notwendig, aber ich verstehe nicht genau den Sinn dahinter
Ne, ist nicht notwendig, das ist eine IDE Anmerkung.

Und muss ich in der toString() Methode mit Gettern arbeiten?
Manchmal wird das gemacht - oder auch this. aber Oracle selber macht das auch nicht.

Meine Frage hierzu ist, ob ich in der Main Klasse den Vornamen, Nachnamen und das geschlecht aus der Superklasse einfügen kann, ohne es selber nochmal ausfüllen zu müssen?

Java:
     @Override
     public String toString(){
         return "Vorname:" + vorname + " Nachname:" + nachname + " Geschlecht:" + geschlecht;
     }
//....

     @Override
     public String toString(){
         return super.toString() + " Matrikelnummer:" + matrikelnummer;
     }
 
Vielen Dank an alle eure Antworten! Das mit return super.toString() funktioniert ja super und der Code sieht gleich viel kompakter aus.
Ich muss jetzt zusätzlich eine Methode schreiben, in der ich ein Feld erstelle mit 6 Instanzen. Das Feld soll 2 Instanzen von Ausweis und Studentenausweis erzeugen und 2 Objekte von Vereinsausweis beinhalten. Die Rückgabe soll das in dieser Methode erzeugte Feld sein. Ich komm da aber irgendwie gerade an keinen Ansatz, wahrscheinlich wieder zulange pausiert wegen Weihnachten.
Kann mir jemand vielleicht nen kleinen Denkanstoß geben?
 
Java:
Ausweis[] ausweise = new Ausweis[6]; // Platz für 6 Ausweise schaffen
ausweise[0] = new Ausweis(...); // 1. Ausweis
ausweise[1] = new Ausweis(...); // 2. Ausweis
ausweise[2] = new Studentenausweis(...); // 3. Ausweis = ein Studentenausweis
usw.

Nachtrag:
Das mit return super.toString() funktioniert ja super
Damit wäre auch geklärt, warum das Schlüsselwort super heißt 😎
 
Zuletzt bearbeitet:

Zurück
Oben