Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
PolymorphieZugriff auf Instanzmethode in Großvaterklasse
ich habe ein kleines Probleme mit dem Zugriff auf eine Instanzmethode der Großvaterklasse. Es ist in der Großvaterklasse eine Methode definiert, welche in der Vaterklasse verdeckt wird. Nun möchte ich aus der Sohnklasse auf die Methode in der Großvaterklasse zugreifen.
laut meinem Buch müsste es gehen mit
Java:
((Großvaterklasse) this).methode();
Leider führt dies aber nicht zum Erfolg. Der Kompiler meckert zwar nicht, aber bei Ausführung werden in der Konsole unendliche viele Zeilen ausgegeben, die so aussehen
Code:
Klasse.methode(Klasse.java:Zeilennummer)
Ich habe auch schon den Aufruf über
Java:
Großvaterklasse.methode();
probiert, was der Kompiler aber mit Fehlermeldung wegen statisch und nicht statisch abbricht.
Vielleicht machst Du mal ein Beispiel, was Du meinst.
Von Verdecken spricht man wenn eine Klasse eine Klassenmethode mit der selben Signatur besitzt wie deren Super Klasse.
Klassenmethoden werden dann allerdings an der Klasse und nicht an einem Objekt der Klasse aufgerufen.
Er meint das er eine überschriebene Instanzmethode hat und die "Version" der Methode in der "Grosvaterklasse" ausführen möchte. Auserhalb der Klasse in der dies passieren soll ist dies afaik wegen Polymorphie nicht möglich, inerhalb der Klasse führt dein Code zum gewünschten Ergebniss.
Die Ausgabe, die du beschreibst hört sich verdächtig nach einer Exception an, poste doch sie doch mal (am besten mit konkretem Code).
mit "verdeckt" ist wahrscheinlich ueberschrieben gemeint.
D.h. in der Grossvater klasse ist eine Methode definiert, die die Vater klasse ueberschreibt. Die Kindklasse will nun aber die Grossvater methode aufrufen und nicht die Vater methode.
wenn das der fall ist wuesste ich keinen weg in der Kindklasse die methode der Grossvaterklasse aufzurufen.
Es klingt eher nach einem design-fehler und dass entweder die Vererbung nicht richtig ist bzw diese Methode anderweitig definiert werden muss
so, also nochmal zu meinem Problem.
Ja ihr habt recht, dass ich Überschreiben meine und nicht Verdecken. Komme da noch ab und zu durcheinander.
Ich kann sicher die Methode in der Sohnklasse so definieren, wie ich sie benötige. Aber ich wollte halt die Methode aus der Großvaterklasse nutzen, so dass ich Änderungen nur einmal durchführen muss.
Dass super.super.methode() nicht funktioniert weiß ich auch bereits.
Nun ist hatl die Frage: Geht der Aufruf über
Java:
((Shape) this).toString()
oder nicht?
Ich bekomme leider keine Exception oder kann Sie zumindest nicht sehen im Prompt. Dort steht nur sehr oft:
Code:
Square.toString(Square.java:14
nun der Code der Dateien, welche ich benutze:
Großvaterklasse: Shape.java
Java:
public class Shape {
/** x-Koordinate des Ursprungs */
protected double xOrigin;
/** y-Koordinate des Ursprungs */
protected double yOrigin;
/**
* Konstruktor für eine Form mit Parametern X-Wert und Y-Wert des Ursprungs
*
*
* @param x
* x-Koordinate des Ursprungs der "Form"
* @param y
* y-Koordinate des Ursprungs
*
*/
public Shape(double x, double y) {
xOrigin = x;
yOrigin = y;
}
/**
* Gibt die Werte des Ursprungspunktes aus in der Form "(x, y)".
* *
*
* @return den Ursprungspunkt als Text
*/
public String origin() {
return ("(" + xOrigin + ", " + yOrigin + ")");
}
/**
* Gibt die Werte des Ursprungspunktes aus .
*
* @return das aktuelle Objekt als Text
*/
public String toString() {
return ("Ursprung: " + origin());
}
}
die Vaterklasse: Rectangle.java
Java:
public class Rectangle extends Shape {
public double xDelta; // Hälfte der Seitenlänge x des Rechtecks
public double yDelta; // Hälfte der Seitenlänge y des Rechtecks
/** Konstruktor zur Erzeugung eines Objektes vom Typ Rectangle
* mit den Parametern x, y, xDelta und yDelta
* unter Verwendung des Konstruktor aus der Oberklasse Shape
*/
public Rectangle (double x, double y, double xDelta, double yDelta) {
super (x, y);
this.xDelta = xDelta;
this.yDelta = yDelta;
}
/**
* Gibt Art des Objektes, die Werte des Ursprungspunktes und die Werte für xDelta und yDelta aus .
*
* @return das aktuelle Objekt als Text
*/
@Override
public String toString() {
return ("Ein Objekt vom Typ " + this.getClass().getName() + " mit dem " + super.toString() + " xDelta: " + xDelta + " yDelta: " + yDelta);
}
}
die Sohnklasse: Square.java
Java:
public class Square extends Rectangle {
public double delta;
public Square (double x, double y, double delta) {
super ( x, y, delta, delta);
this.delta = delta;
}
@Override
public String toString() {
return ("Ein Objekt vom Typ " + this.getClass().getName() + " mit dem " + ((Shape) this).toString() + " und Delta: " + delta);
}
}
dazu noch die Klasse zum Erzeugen vom Objekt: ShapeTester.java
Java:
public class ShapeTester {
public static void main (String [] args ) {
Square square1 = new Square (30,20,5); // Erzeugen eines neuen Square Objekts
Reporter.report (square1);
}
}
und die Reporter.java
Java:
public class Reporter {
/**
* in der Methode werden die einzelnen Methoden der geometrischen Formen aufgerufen
* @param Objekte als Typ Shape, da alle Objekte von der Superklasse Shape abstammen
*/
public static void report(Shape s) {
System.out.println (s.toString());
System.out.println();
}
}
In diesem Fall geb ich den anderen Recht, dein Problem ist eindutig ein Designfehler.
Schreib halt einfach anstatt [c]super.toString()[/c] das was in toString steht [c]"Ursprung:" +origin()[/c]
Was die Exception angeht: Du hast unbeabsichtigt eine Endlos-Rekursion eingebaut, was zu einem StackOverflowError führt, und da die Konsol nur eine begrenzte Anzahl Zeilen speichert, siehst du den Anfang der Ausgabe nicht mehr. Daraus folgere ich, dass die man eine doppelt überschrieben Methode nicht in der Urfassung aufrufen kann, was eigentlich nur eine korrkte Umsetzung von Polymorphie ist.
wenn du in Windows arbeitest, dann leite die Ausgabe mal in eine Datei um: [c]java ShapeTester > Ausgabe.txt[/c]
implementieren, die dann in der toString() der Subklassen verwendet wird. Dann könnte man sich für die Klasse Square sogar das überschreiben der toString() Methode sparen.
Wobei mir aus dem Code nicht unbedingt klar wird wozu man die Klasse Square überhaupt benötigt, da sie keine anderen Möglichkeiten als die Klasse Rectanlge bietet. So wie es aussieht würde es reichen der Klasse Rectangle einen zweiten Konstruktor (wie der in Square) zu spendieren.
Über den Unsinn der Klasse Square brauchen wir ja nicht streiten. Leider war dies so vorgegeben und nicht meine Idee.
Ich habe es jetzt auch ähnlich gelöst, wie von Mediafreak geschrieben und habe mich auf die Funktion
Code:
origin()
in der Klasse Shape bezogen im Fall von Square.
Und ich denke ich habe jetzt eine ganz vernünftige Lösung gefunden, welche der Aufgabenstellung entspricht.
Die Frage kam aber auf, weil der Prof meinte, dass ein Zugriff mit
Code:
((Shape) this).toString()
auf die Instanzmethode der Großvaterklasse möglich sei!
dann sagt der Prof Unsinn. nur wenn man ((Shape)this).toString() aufruft macht das noch nix.... sonst wuerde ja ((Object)this).tostring() immer die Object toString aufrufen, tuts aber nicht. this bleibt nun mal die Unterklasse, egal was man davor schreibt.
super.methode() spricht die Methode der Oberklasse an, der compiler macht da nicht irgendwelche casts