webentwicklung-frage-antwort-db.com.de

Kann Java eine überschriebene übergeordnete Methode in anderen Objekten aufrufen, jedoch nicht in einem Untertyp?

hier arbeitet Java-Code

class Cup {
    public String sayColor() {
        return "i have a color .";
    }
}

class TCup extends Cup{
    public String sayColor(){
        System.out.println(super.getClass().getName());
        return super.sayColor()+"color is tee green.";
    }
}

class MyTCup extends TCup {
    public String sayColor(){
        System.out.println(super.getClass().getName());
        return super.sayColor()+"but brushed to red now!";
    }
}
class Test {
    public static void main(String[] args) {
        Cup c = new MyTCup();
        System.out.print(c.sayColor());
    }
}

und Ausführen der Test-Klasse druckt

MyTCup
MyTCup
i have a color .color is tee green.but brushed to red now!

frage 1: Zur Laufzeit ist der Typ des Objekts C MyTCup, es kann jedoch immer die Supermethode aufgerufen werden. Gibt es einen Methodenstapel im Speicher in MyTCup, nachdem das Objekt initialisiert wurde, und kann es zur Laufzeit wie durchlaufen der Code ?

frage 2: Es gibt keine Möglichkeit, die Super-Methode in anderen Objekten aufzurufen. Wie ich weiß, kann C++ jederzeit in eine übergeordnete Methode übergehen. Warum Java-Design so?

35
sting

Sie können die Supermethode nicht in anderen Objekten aufrufen - das würde die Kapselung verletzen. Der springende Punkt ist, dass das Objekt steuert, was seine überschriebenen Methoden tun. Beispielsweise können Sie die add-Methode einer Sammlung überschreiben, um unter bestimmten Umständen eine Ausnahme auszulösen, sodass sichergestellt werden kann, dass nur "gültige" Elemente zur Sammlung hinzugefügt werden. Das wäre sinnlos, wenn Anrufer es einfach mit einem Cast umgehen könnten!

Der einzige Grund, warum ein Objekt super.foo() für sich selbst aufrufen kann, ist die Implementierung eines Aufrufs mithilfe der übergeordneten Implementierung. Es ist Sache des Codes in der Klasse, sicherzustellen, dass dies nur sinnvoll geschieht. Um das Add-In-a-Collection-Beispiel zu verwenden, müsste die Auflistung add überschrieben werden, wenn das validierte Element in die Auflistung einige aufgenommen werden soll, was mit super.add() geschehen würde.

Beachten Sie, dass Sie aus demselben Grund der Kapselung only Ihre übergeordnete Implementierung aufrufen können, nicht die Großelternimplementierung - also super.foo() ist gültig, aber super.super.foo() nicht.

68
Jon Skeet

1:

Ihre Frage ist nicht ganz klar. Was meinen Sie mit "Aufruf zur Laufzeit wie Code"? Wenn Sie fragen, wie die Instanz c weiß, was ihre Superklasse ist, wird die Klassenhierarchie im Arbeitsspeicher gespeichert und kann von der VM abgerufen werden.

2:

In Java können Sie tatsächlich eine Instanz in ihre übergeordnete Instanz umwandeln. Es ist nur so, dass beim Aufruf einer Methode für eine Instanz immer die tatsächliche Klasse der Instanz verwendet wird, nicht die Klasse zum Zeitpunkt der Kompilierung. Das heißt In Java werden alle Methoden in C++ als "virtuell" bezeichnet. Warum dies entschieden wurde, weiß ich nicht.

Edit: Eigentlich erklärt Jon Skeet sehr schön, warum man keine Methode einer Superklasse für eine Instanz einer Unterklasse aufrufen kann, daher weiß ich jetzt :-).

1
sleske

Eigentlich ist das möglich, aber Sie müssen eine Methodik verwenden, die nur mit Ihrem Code funktioniert.
Fügen Sie in der Superklasse der Methode den Parameter "Class" hinzu, wie in: 

public String sayColor(Class classFilter){...

jetzt überprüfen Sie bei jeder Überschreibung, ob die aktuelle Unterklasse diejenige des angegebenen Filters ist:

if(TCup.class!=classFilter)return super.sayColor(classFilter);
return "some text for TCup only";

Ich habe exklusiv codiert. Sie können weitere Parameter hinzufügen oder mit Null vergleichen, sodass Sie Ergebnisse mit den Superklassen verknüpfen und Ihre Kreativität einsetzen können :)

0
Aquarius Power

Sie können eine neue Hilfsmethode in der Unterklasse definieren, damit Sie das Original nicht überschreiben - rufen Sie das an - es kann die Supermethode aufgerufen werden oder nicht, je nachdem, was Sie möchten.

0
rogerdpack