Typumwandlung von polymorphen Java -Objekten <BR /> Die hier erwähnte Objekttypkonvertierung bezieht sich auf ein Objekt mit einer Vererbungsbeziehung, nicht auf ein Objekt jeglicher Art. Bei einem Objekt, das keine Vererbungsbeziehung hat, löst die Java -Laufzeit eine Ausnahme von java.lang.ClassCastException aus.
In der Vererbungskette nennen wir die Unterklasse -Konvertierung in die übergeordnete Klasse "Aufwärtstransformation" und die Konvertierung der Elternklasse in die untergeordnete Klasse "Abwärtstransformation".
Oft definieren wir Variablen als die Art der übergeordneten Klasse, beziehen sich jedoch auf das Objekt der untergeordneten Klasse. Wenn das Programm ausgeführt wird, verwendet es eine dynamische Bindung, um den Aufruf auf Unterklassenmethoden zu realisieren, dh Polymorphismus.
Um jedoch die Funktionen, die einige übergeordnete Klassen nicht haben, zu vervollständigen, müssen wir jedoch die nach oben transformierten Subklassenobjekte in Unterklassen umwandeln und die Unterklasse-Methoden aufrufen, die nach unten transformiert werden.
HINWEIS: Das Objekt der übergeordneten Klasse kann nicht direkt in einen Unterklassentyp gegossen werden, und das Subklassenobjekt nach der Aufwärtstransformation kann nur erneut in einen Unterklassen -Typ konvertiert werden. Mit anderen Worten, Unterklasseobjekte müssen nach oben transformiert werden, bevor sie sich nach unten transformieren können. Bitte beachten Sie den folgenden Code:
Public Class Demo {public void main (String args []) {Superclass Superobj = New SuperClass (); übergeordnetes Objekt ist ein Subklasse -Typ // Sonobj2 = (Sonclass) Superobj;Entfernen Sie den Kommentar in Zeile 7, und eine Ausnahme wird zur Laufzeit ausgeführt, aber die Zusammenstellung kann übergeben werden.
Da es Risiken beim Übergang nach unten gibt, verwenden Sie beim Erhalten eines Verweiss auf die übergeordnete Klasse den Instanz -Operator, um festzustellen, ob das Objekt die gewünschte Unterklasse ist.
public class Demo {public void main (String args []) {Superclass Superobj = new Superclass (); = (Sonclass) Superobj; ) Superobj;} else {System.out.println ("② kann nicht konvertiert werden"); Auslaufergebnisse:
① kann nicht konvertieren
Zusammenfassung: Die Typumwandlung eines Objekts wird überprüft, wenn das Programm ausgeführt wird.
Java -Polymorphismus und dynamische Bindung <br /> In Java können die Variablen der übergeordneten Klasse auf Instanzen der übergeordneten Klasse oder Instanzen der untergeordneten Klasse verweisen.
Bitte lesen Sie zuerst ein Stück Code:
public class Demo {public void main (String [] args) {Animal OBJ = New Animal (); .Cry (); Call of Cat public void cry () {System.out.println ("meow ~"); }} Auslaufergebnisse:
Ich weiß nicht, wie man Meow ~ Wolle nennt ~
Der obige Code definiert drei Klassen, nämlich Tier-, Katze und Hund. Die OBJ -Variable verfügt über Typtier, das auf Fälle der Tierklasse sowie auf Fälle von Katzen- und Hundeklassen hinweisen kann, was korrekt ist. Das heißt, die Variablen der übergeordneten Klasse können sich auf Instanzen der übergeordneten Klasse oder Instanzen der untergeordneten Klasse beziehen. Beachten Sie, dass die Umgebung falsch ist, weil alle Katzen Tiere sind, aber nicht alle Tiere Katzen sind.
Es ist zu erkennen, dass OBJ entweder ein Mensch, eine Katze oder ein Hund sein kann. Polymorphismus bezieht sich auf eine Sache mit unterschiedlichen Formen oder Formen.
Zum Beispiel haben "Menschen" auch viele verschiedene Ausdrücke oder Implementierungen. , Lehrer oder Arzt im nächsten Leben.
Es gibt drei notwendige Bedingungen, damit Polymorphismus existiert: Vererbung, Umschreiben und Elternvariablen beziehen sich auf Subklassenobjekte.
Beim Aufrufen einer Methode unter Verwendung einer polymorphen Methode:
Überprüfen Sie zunächst, ob die Methode in der übergeordneten Klasse vorhanden ist.
Wenn die Unterklasse die Methode überschreibt, wird die Methode der Unterklasse aufgerufen, andernfalls wird die übergeordnete Klassenmethode aufgerufen.
Aus dem obigen Beispiel können wir feststellen, dass ein Vorteil des Polymorphismus darin besteht, dass Sie, wenn es viele Unterklassen gibt, keine Mehrfachvariablen definieren müssen. Bitte sehen Sie sich das folgende Beispiel an:
Public Class Demo {public static void main (String [] args) {// Mit Hilfe des Polymorphismus kann der Besitzer viele Tiere master ma = new Master () füttern; ); ) {System.out.println ("Ich bin ein kleines Tier, esse" + F.Getfood ()); Eine kleine Katze isst " + f.getfood ());}} Klasse Dog erweitert Tier {public void eat (Food f) {System.out.println (" Ich bin ein Hund, esse " + f. Getfood ()) ; String Getfood () {return "bone"; Auslaufergebnisse:
Ich bin ein kleines Tier, esse Dinge, ich bin eine kleine Katze, esse Fisch, ich bin ein Hund, esse Knochen
Die Feed -Methode der Meisterklasse hat zwei Parameter, nämlich den Tierart und den Lebensmitteltyp. Verschiedene Tiere.
Dynamische Bindung
Um die Art des Polymorphismus zu verstehen, sprechen wir über den detaillierten Prozess der nachstehenden Methoden von Java -Aufrufen.
1) Der Compiler überprüft den Deklarationstyp und den Methodennamen des Objekts.
Angenommen, Obj.func (Param) wird aufgerufen, OBJ ist ein Objekt der Katzenklasse. Es ist zu beachten, dass es mehrere Methoden mit Namen mit Func, aber unterschiedlichen Parametern geben kann. Beispielsweise können Methoden Func (int) und Func (String) existieren. Der Compiler listet alle Methoden, die Func in Cat -Klasse und Methoden auf den Zugriff auf Attribut öffentlich genannt werden, und Func in seinem Tierklassentier auf.
Auf diese Weise erhält der Compiler eine Liste aller möglichen aufgerufenen Kandidatenmethoden.
2) Als nächstes überprüft der Editor die Parametersignatur beim Aufrufen der Methode.
Wenn in allen Methoden, die als Func bezeichnet werden, eine Methode gibt, die genau mit der bereitgestellten Parametersignatur übereinstimmt, wählen Sie diese Methode aus. Dieser Prozess wird als Überlastungsauflösung bezeichnet. Wenn beispielsweise Func ("Hallo") aufgerufen wird, wählt der Compiler Func (String) anstelle von Func (int) aus. Aufgrund der existierenden automatischen Konvertierung kann int in doppelter Verfahren konvertiert werden. Ende oder mehrere Methoden stimmen damit überein und erfassen Sie den Fehler.
Auf diese Weise erhält der Compiler die Methodenname und die Parametersignatur, die aufgerufen werden muss.
3) Wenn der Methodenmodifikator privat, statisch, endgültig ist (statisch und endgültig wird später erklärt) oder ein Konstruktor, kann der Compiler genau wissen, welche Methode aufgerufen werden sollte. .
Entsprechend hängt die aufgerufene Methode vom tatsächlichen Typ des Objekts ab und implementiert die dynamische Bindung zur Laufzeit. Wenn der Editor beispielsweise Func ("Hello") aufruft, wird der Editor dynamische Bindung verwendet, um eine Anweisung zu generieren, die Func (String) aufruft.
4) Wenn das Programm dynamische Bindung ausführt und verwendet, um die Methode aufzurufen, ruft das JVM definitiv die Methode der Klasse auf, die für den tatsächlichen Typ des von OBJ verwiesenen Objekts am besten geeignet ist. Wir haben angenommen, dass OBJs tatsächlicher Typ Katze ist, bei dem es sich um eine Unterklasse von Tier handelt, und sie wird aufgerufen, wenn Func (String) in Katze definiert ist, sonst wird er in der Tierklasse und seiner Elternklasse durchsucht.
Jeder Aufruf der Methode erfordert die Suche, die ziemlich teuer ist. Auf diese Weise kann die virtuelle Maschine, wenn die Methode tatsächlich aufgerufen wird, diese Tabelle nur nachschlagen. Im obigen Beispiel sucht der JVM die Methode -Tabelle der Katzenklasse, um eine Methode zu finden, die mit dem Anruf bei Func ("Hallo" übereinstimmt. Diese Methode kann entweder Cat.Func (String) oder Animal.Func (String) sein. Beachten Sie, dass der Compiler die Methode Tabelle der übergeordneten Klasse durchsucht, wenn Super.func ("Hallo" aufgerufen wird.
Unter der Annahme, dass die Tierklasse drei Methoden enthält: Cry (), getName () und getage (), lautet seine Methode -Tabelle wie folgt:
cry () -> Animal.cry ()
GetName () -> Animal.getName ()
getage () -> Animal.getage ()
Tatsächlich hat Animal auch ein standardmäßiges übergeordnetes Klassenobjekt (das später erklärt wird), das die Objektmethode erbt, sodass die oben aufgeführten Methoden nicht vollständig sind.
Unter der Annahme, dass die CAT -Klasse die Cry () -Methode in der Tierklasse überschreibt und eine neue Methode fügt Climbree () hinzufügt, lautet seine Parameterliste:
cry () -> cat.cry ()
GetName () -> Animal.getName ()
getage () -> Animal.getage ()
blodtree () -> cat.climbTree ())
Beim Ausführen lautet der Prozess des Aufrufens der Methode obj.cry () wie folgt:
Der JVM greift zunächst auf die Methodentabelle des tatsächlichen OBJ -Typs zu, die die Methodentabelle der Tierklasse oder die Methode Tabelle der Katzenklasse und ihrer Unterklassen sein kann.
JVM sucht nach einer Methode, die Cry () in der Methode Tabelle entspricht, und nachdem Sie sie gefunden haben, wissen Sie, zu welcher Klasse sie gehört.
Das JVM nennt diese Methode.