Dieser Artikel stellt hauptsächlich die detaillierte Erklärung und einfache Beispiele der Java-Transformation (Aufwärts- oder Abwärtstransformation) vor
Bei der Java-Programmierung stoßen wir häufig auf Typkonvertierung Die Konvertierung von Objekttypen umfasst hauptsächlich die Aufwärts- und Abwärtskonvertierung.
Aufwärtstransformation
Wir sagen das in der Realität oft: Diese Person kann singen. Dabei ist es uns egal, ob die Person schwarz oder weiß, ein Erwachsener oder ein Kind ist, weshalb wir lieber den abstrakten Begriff „Person“ verwenden. Ein weiteres Beispiel: Ein Spatz ist eine Vogelart (eine Unterart eines Vogels) und ein Vogel ist eine Tierart (eine Unterart eines Tieres). In der Realität sagen wir das oft: Spatzen sind Vögel. Diese beiden Aussagen sind eigentlich die sogenannte Aufwärtstransformation. Für den Laien bedeutet dies die Transformation einer Unterklasse in eine übergeordnete Klasse. Dies steht auch im Einklang mit den von Java vertretenen abstrakt-orientierten Programmierideen. Schauen wir uns den folgenden Code an:
package a.b; public class A { public void a1() { System.out.println("Superclass"); } }
A-Unterklasse B:
package a.b; public class B extends A { public void a1() { System.out.println("Childrenclass"); //覆盖父类方法 } public void b1(){} //B类定义了自己的新方法 }
C-Klasse:
package a.b; public class C { public static void main(String[] args) { A a = new B(); //向上转型 a.a1(); } }
Wenn Sie C ausführen, handelt es sich bei der Ausgabe um eine Superklasse oder eine Kinderklasse? Nicht die Superklasse, die Sie ursprünglich erwartet hatten, sondern die Kinderklasse. Dies liegt daran, dass a tatsächlich auf ein Unterklassenobjekt verweist. Natürlich müssen Sie sich keine Sorgen machen, die Java Virtual Machine erkennt automatisch und genau, welche spezifische Methode aufgerufen werden soll. Aufgrund der Aufwärtstransformation verliert das a-Objekt jedoch Methoden, die sich von der übergeordneten Klasse unterscheiden, z. B. b1(). Manche Leute fragen sich vielleicht: Ist das nicht unnötig? Wir können auf jeden Fall so schreiben:
B a = new B(); a.a1();
Das stimmt! Dadurch gehen jedoch die abstraktionsorientierten Programmierfunktionen verloren und die Skalierbarkeit wird verringert. Darüber hinaus kann die Aufwärtstransformation auch den Programmieraufwand reduzieren. Schauen wir uns die folgende Monitorklasse an: Monitor:
package a.b; public class Monitor{ public void displayText() {} public void displayGraphics() {} }
LCDMonitor ist eine Unterklasse von Monitor:
package a.b; public class LCDMonitor extends Monitor { public void displayText() { System.out.println("LCD display text"); } public void displayGraphics() { System.out.println("LCD display graphics"); } }
Cathode Ray Die Röhre Die Anzeigeklasse CRTMonitor ist natürlich eine Unterklasse von Monitor:
package a.b; public class CRTMonitor extends Monitor { public void displayText() { System.out.println("CRT display text"); } public void displayGraphics() { System.out.println("CRT display graphics"); } }
Plasmaanzeige PlasmaMonitor ist auch eine Unterklasse von Monitor:
package a.b; public class PlasmaMonitor extends Monitor { public void displayText() { System.out.println("Plasma display text"); } public void displayGraphics() { System.out.println("Plasma display graphics"); } }
Jetzt gibt es eine MyMonitor-Klasse. Unter der Annahme, dass es keine Aufwärtstransformation gibt, lautet der MyMonitor-Klassencode wie folgt:
package a.b; public class MyMonitor { public static void main(String[] args) { run(new LCDMonitor()); run(new CRTMonitor()); run(new PlasmaMonitor()); } public static void run(LCDMonitor monitor) { monitor.displayText(); monitor.displayGraphics(); } public static void run(CRTMonitor monitor) { monitor.displayText(); monitor.displayGraphics(); } public static void run(PlasmaMonitor monitor) { monitor.displayText(); monitor.displayGraphics(); } }
Vielleicht haben Sie festgestellt, dass der obige Code viele doppelte Codes enthält und nicht einfach zu warten ist. Mit der Aufwärtstransformation kann der Code prägnanter sein:
package a.b; public class MyMonitor { public static void main(String[] args) { run(new LCDMonitor()); //向上转型 run(new CRTMonitor()); //向上转型 run(new PlasmaMonitor()); //向上转型 } public static void run(Monitor monitor) { //父类实例作为参数 monitor.displayText(); monitor.displayGraphics(); } }
Wir können auch die Schnittstelle verwenden, zum Beispiel:
package a.b; public interface Monitor { abstract void displayText(); abstract void displayGraphics(); }
Ändern Sie die Flüssigkristallanzeigeklasse LCDMonitor leicht:
package a.b; public class LCDMonitor implements Monitor { public void displayText() { System.out.println("LCD display text"); } public void displayGraphics() { System.out.println("LCD display graphics"); } }
Die Änderungsmethoden der CRTMonitor- und PlasmaMonitor-Klassen ähneln denen von LCDMonitor, MyMonitor muss jedoch überhaupt nicht geändert werden.
Es ist ersichtlich, dass die Aufwärtstransformation den Polymorphismus der -Klasse widerspiegelt und die Einfachheit des Programms erhöht.
Abwärtstransformation
Die Transformation einer Unterklasse in eine Elternklasse ist eine Aufwärtstransformation, und umgekehrt ist die Transformation einer Elternklasse in eine Unterklasse eine Aufwärtstransformation eine Abwärtstransformation. Allerdings kann die Abwärtstransformation einige Probleme verursachen: Wir können sagen, dass ein Spatz ein Vogel ist, aber wir können nicht sagen, dass ein Vogel ein Spatz ist. Schauen wir uns das folgende Beispiel an:
Klasse A:
package a.b; public class A { void aMthod() { System.out.println("A method"); } }
Unterklasse B von A:
package a.b; public class B extends A { void bMethod1() { System.out.println("B method 1"); } void bMethod2() { System.out.println("B method 2"); } }
Klasse C:
package a.b; public class C { public static void main(String[] args) { A a1 = new B(); // 向上转型 a1.aMthod(); // 调用父类aMthod(),a1遗失B类方法bMethod1()、bMethod2() B b1 = (B) a1; // 向下转型,编译无错误,运行时无错误 b1.aMthod(); // 调用父类A方法 b1.bMethod1(); // 调用B类方法 b1.bMethod2(); // 调用B类方法 A a2 = new A(); B b2 = (B) a2; // 向下转型,编译无错误,运行时将出错 b2.aMthod(); b2.bMethod1(); b2.bMethod2(); } }
Aus dem obigen Code können wir den Schluss ziehen, dass die Abwärtstransformation die Verwendung von Cast erfordert. Führen Sie das C-Programm aus und die Konsole gibt Folgendes aus:
Exception in thread "main" java.lang.ClassCastException: a.b.A cannot be cast to a.b.B at a.b.C.main(C.java:14) A method A method B method 1 B method 2
Tatsächlich haben Sie die Kommentare nach dem Abwärtstransformationscode in Fettdruck bereits gewarnt, dass ein Laufzeitfehler auftreten wird. Warum ist der Abwärtstransformationscode im ersten Satz in Ordnung, der Code im zweiten Satz jedoch falsch? Dies liegt daran, dass a1 auf ein Objekt der Unterklasse B zeigt, sodass das Instanzobjekt b1 der Unterklasse B natürlich auch auf a1 zeigen kann. Und a2 ist ein übergeordnetes Klassenobjekt, und das untergeordnete Klassenobjekt b2 kann nicht auf das übergeordnete Klassenobjekt a2 verweisen. Wie kann ich also eine Laufzeit-ClassCastException vermeiden, wenn ich einen Downcast durchführe? Verwenden Sie einfach die in Abschnitt 5.7.7 erlernte Instanz. Ändern wir den Code der Klasse C:
A a2 = new A(); if (a2 instanceof B) { B b2 = (B) a2; b2.aMthod(); b2.bMethod1(); b2.bMethod2(); }
Nach der Verarbeitung auf diese Weise müssen wir uns bei der Typkonvertierung keine Sorgen mehr über ClassCastException-Ausnahmen machen.
Das obige ist der detaillierte Inhalt vonJava-Casting-Beispiele: Up- oder Down-Casting. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!