[JAVA] Polymorphismus-Quiz
Java Puzzlers Adventskalender 2016 befindet sich in einer bedauerlichen Situation, in der nur ein Beitrag fehlt, daher werde ich den Artikel für Tag 5 ersetzen Ich werde.
Problem
class MyTest
{
private static class A {
String message = "hello";
Consumer<String> hello = s -> System.out.print(message + s);
void hello(String s) { this.hello.accept(s); }
}
private static class B extends A {
String message = "Hallo";
void hello(String s) { this.hello.accept(s); }
}
public static void main(String[] args) {
A b = (A) new B();
b.hello(" world");
System.out.print("/");
b.hello.accept(" world");
}
}
Das Ergebnis der Ausführung des obigen Codes ist
- [] A. Hallo Welt / Hallo Welt
- [] B. Hallo Welt / Hallo Welt
- [] C. Hallo Welt / Hallo Welt
- [ ] D. hello world/hello world
- [] E. Kompilierungsfehler
Richtige Antwort
Die Antwort ist
- [x] D. hello world/hello world
Erläuterung
Es mag auf den ersten Blick kompliziert erscheinen, aber wenn Sie den Polymorphismus richtig verstehen, sollten Sie ihn sofort lösen können. Werfen wir einen Blick auf die Verarbeitung der main
-Methode.
- In der ersten Zeile der Methode "main" wird die Implementierungsvariable "b" vom Typ "A" deklariert. Der Upcast-Prozess mit dem Namen "(A)" ist geschrieben, aber tatsächlich ist es eine Arbeit, die der Compiler automatisch ausführt. Er ist also nur ärgerlich und bedeutungslos (obwohl er natürlich keinen Fehler verursacht).
- Bei Verwendung der Methode "b" prüft der Compiler zunächst, ob die Implementierung über diese Methode verfügt (zweite Zeile). In der Klasse B gab es eine Methode namens "Hallo". Die Überschreibung ist nicht angegeben, aber da es keinen Unterschied in der Signatur gibt, können wir sehen, dass die "Hallo" -Methode der übergeordneten Klasse überschrieben wurde. Die Regeln des Polymorphismus führen die "Hallo" -Methode der Klasse "B" aus.
- Die Methode "Hallo" ruft das Feld der Consumer-Funktion "Hallo" auf, aber leider existiert "Hallo" nur in der Klasse "A". Daher ist es unvermeidlich, die Funktion "Hallo" in der Klasse "A" zu verwenden. (Übrigens sind doppelte Methoden- und Feldnamen zulässig, sodass kein Kompilierungsfehler auftritt.)
- Die Funktion "Hallo" verwendet das Feld "Nachricht". Die "Nachricht" der Klasse "A" ist "Hallo", daher wird die Ausgabe "Hallo Welt" sein. Es gibt auch ein Feld namens "Nachricht" in Klasse "B", aber es hat nichts mit der "Hallo" -Funktion zu tun, die Sie jetzt verwenden.
- Außerdem sieht es in der 4. Zeile von "main" so aus, als würden Sie die "Hallo" -Funktion des "b" -Objekts verwenden. Beachten Sie jedoch, dass es keine Überschreibungen von Feldvariablen gibt. Die Funktion "Hallo" definiert die Verarbeitungsprozedur wie die Methode "Hallo", ist jedoch im Wesentlichen eine Feldvariable wie "Nachricht". Welches Feld verwendet wird, hängt daher vom Referenztyp zum Zeitpunkt der Deklaration ab. Da es als "A" deklariert wurde, wird die "Hallo" -Funktion der Klasse "A" verwendet und entspricht dem Ausgabeergebnis der zweiten Zeile.
Referenz
- https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
- https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/Consumer.html