Vererbung this innerhalb von super

Oekel

Mitglied
Könnt ihr mir bitte Links/Quellen/Stichwörter nennen, die folgenden Testcode/Ausgabe erklären?

Java:
package testVererbung;

public class main {
    public static void main(String[] args) {
        Grossvater person = new Kind();
        System.out.println(person); //wandern mit 40 und geradem Rücken
        System.out.println(person.alter);//80
    }
}
public class Grossvater {
    int alter = 80;
    public String ruecken() {
        return "kaputtem";
    }
}
public class Vater extends Grossvater {
    int alter = 40;
    public String wandern()
    {
        return "wandern mit "+alter+" und "+this.ruecken() +" Rücken";
    }
    public String ruecken() {
        return "krummen";
    }
    public String getAlter()
    {
        return ""+this.alter;
    }
}
public class Kind extends Vater {

    int alter = 16;
    public String toString()
    {
        return super.wandern();
    }
    public String wandern()
    {
        return "wandern mit "+getAlter()+"und "+this.ruecken();
    }
    public String ruecken() {
        return "geradem";
    }
}

---------------------------------
Mir ist soweit klar,dass innerhalb von "Vater" es keinen Unterschied macht, ob ich ruecken() oder this.ruecken() aufrufe. Es wird immer die überschriebene Methode von der aktuellen Instanz verwendet. Gibt es denn eine Möglichkeit in Java dieses zu verhindern? (Wüsste nicht wie, da es der Vererbungslehre wiederspricht!?)
Und nun noch kurz zu den Variablen "alter". Gilt hier keine Vererbungstheorie?

Grüße Oekel
 
Zuletzt bearbeitet von einem Moderator:
sout(person) ruft #toString auf der Instanz von Kind auf.
In toString wird super.wandern aufgerufen, also #wandern von Vater. in wandern wird this.alter (=40) benutzt, was das alter von Vater ist. Das Alter von Kind kennt Vater gar nicht, und das von Großvater wird hinter dem von Vater "versteckt". this.ruecken() ruft dann die #rücken-Implementierung von Kind auf, wie du auch schon gesagt hast, = "gerade".

person ist als Großvater deklariert, also wird bei person.alter das alter vom Großvater zurückgeben.

Und nun noch kurz zu den Variablen "alter". Gilt hier keine Vererbungstheorie?
Auch wenn die 3 Variablen alter gleich heißen, es sind unterschiedliche Variablen!


Mir ist soweit klar,dass innerhalb von "Vater" es keinen Unterschied macht, ob ich ruecken() oder this.ruecken() aufrufe. Es wird immer die überschriebene Methode von der aktuellen Instanz verwendet. Gibt es denn eine Möglichkeit in Java dieses zu verhindern? (Wüsste nicht wie, da es der Vererbungslehre wiederspricht!?)
Man kann verhindern, dass Methoden überschrieben werden. Tut man das nicht, wird immer die "niedrigste" Implementierung (die der Instanz) verwendet.
 
sout(person)
....in wandern wird this.alter (=40) benutzt, was das alter von Vater ist. Das Alter von Kind kennt Vater gar nicht ...

vs.
sout(person)
....this.ruecken() ruft dann die #rücken-Implementierung von Kind auf....
(Tut man das nicht), wird immer die "niedrigste" Implementierung (die der Instanz) verwendet.

Hat mich da etwas verwirrt. Also der 'this' Aufruf auf Basis von Variablen vs Methoden.
Denn innerhalb von Vater komme ich ja mit "alter oder this.alter" auf '40' und mit "super.alter" auf '80'. (Selbst wenn die Instanz ein "Kind" ist ; habe also keine Chance dynamisch auf die unterste Ebene zu kommen außer mittels getter())
Jedoch mit "ruecken() oder this.ruecken()" auf 'gerade' und mit "super.ruecken()" auf 'kaputtem'.
(Somit also keine Chance auf die Methode des Vaters innerhalb von Vater zu kommen, außer die Instanz ist 'nur' ein Vater)

Habe ich das nun korrekt außeinander gezogen?

Grüße Oekel
 
Hat mich da etwas verwirrt. Also der 'this' Aufruf auf Basis von Variablen vs Methoden.
Variablen und Methoden sind vollkommen unterschiedlich - Variablen existieren einfach, Methoden haben eine Implemenation und eine können damit auch überschrieben werden. Mehrfach eine Variable deklarieren führt nur neue Variablen ein (die gleich heißen->ganz schlechter Stil), ändert aber nichts an der ursprünglichen.

Denn innerhalb von Vater komme ich ja mit "alter oder this.alter" auf '40' und mit "super.alter" auf '80'. (Selbst wenn die Instanz ein "Kind" ist ; habe also keine Chance dynamisch auf die unterste Ebene zu kommen außer mittels getter())
this.alter und super.alter sind unterschiedliche Variablen! Das ist eben etwas anderes, als (überschriebene) Methoden.

Jedoch mit "ruecken() oder this.ruecken()" auf 'gerade' und mit "super.ruecken()" auf 'kaputtem'.
(Somit also keine Chance auf die Methode des Vaters innerhalb von Vater zu kommen, außer die Instanz ist 'nur' ein Vater)
Man "kennt" seine eigene und die super-Implementierung. #super braucht man uU, um die eigene Implementierung überschreiben zu können.
Ausgeführt wird aber immer die Implementierung der aktuellen Instanz.

Wenn es während der Laufzeit bei Methoden die nicht final sind relevant ist, ob jetzt super, this, oder überschriebenes aufgerufen wird, ist irgendwas grundsätzliches am Design falsch.

ZB beim Beispiel oben: Ein Kind ist nicht immer ein Vater (und ein Großvater), die Umsetzung so ist also mehr als Zweifelhaft. (andersrum wäre Ok, also Kind->Vater->Großvater (jeder Großvater ist schließlich irgendwessen Vater, und jeder Vater das Kind von irgendwem)).
Genauso das mehrfache deklarieren von alter, gleich heißende Variablen sind immer ziemlich schlechter Stil und führen nur zu Verwirrung.
 
Ok danke soweit. Das Bsp. von mir ist in der Tat sehr Zweifelhaft, erfüllt aber denke ich den Zweck und zeigt wieso ich verwirrt war. Konkret und abschließend ist zu sagen, dass ich gerade wirklich schlecht geschriebenen/kopierten Code refaktore und eben an meinem eigenen Verstand gezweifelt habe, als ich sah wie eine KOMPLETTE Klasse (die vermutlich "etwas" erweitern sollte) mit ALL ihren Methoden und privaten Variablen incl. Gettern/Settern kopiert wurde, ein extend hinter geklatscht und auf das original zwei drei Methoden leicht angepasst wurden. Da fragte ich mich halt, ob innerhalb der neuen Methoden die alten (gleichgebliebenen) nicht mehr verwendet werden können/dürfen/sollen. Was natürlich bei 1:1 CnP totaler Blödsinn ist. ......wenn ihr wüsstet welcher namenhafter Hersteller dahinter steht (*Kopfschüttel*)....
 
Die der Superklasse können mit super verwendet werden - andere nicht.

Das ist klar 😉 Ich glaube aber du hattest mich falsch verstanden (ist auch keine Frage mehr, sondern ein Erklärungsversuch)

Ich befinde mich in der ERBENDEN Klasse und rufe mit super die Funktionen der ELTERNKLASSE auf:
Wenn nun aber die ELTERNKLASSE zwei Methoden hat von der die eine auf die andere verweist und beide überschrieben wurden, dann besteht nicht die Chance (und das ist auch gut so!!!!) dass die erste Methode (welche wir von "unten" aufrufen) der Elternklasse die zweite (Implementierung) von IHR (Elternklasse) aufruft (und steht dort noch 100Mal "this" vor), statt dessen überschriebenen Methode in der ERBENDEN, (von der der Aufruf ursprünglich ja kam). Also noch Mal "this" hat nichts mit der Definition zu tun, wo es niedergeschrieben wurde (das wollte ich nämlich für kurze Zeit glauben), sondern mit der Instanz, die später existiert.
 

Zurück
Oben