Cet article vous présente une introduction à l'utilisation de la transformation ascendante et descendante de Java (avec code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
1 Transformation vers le haut (sous-classe en classe parent)
Exemple :
package a.b; public class A { public void a1() { System.out.println("Superclass"); } } A的子类B: package a.b; public class B extends A { public void a1() { System.out.println("Childrenclass"); //覆盖父类方法 } public void b1(){} //B类定义了自己的新方法 } C类: package a.b; public class C { public static void main(String[] args) { A a = new B(); //向上转型 a.a1(); } }
Si vous exécutez C, la sortie est-elle Superclass ou Childrenclass ? Pas la Superclasse à laquelle vous vous attendiez à l'origine, mais la Childrenclass. En effet, a pointe en fait vers un objet de sous-classe. Bien sûr, vous n'avez pas à vous inquiéter, la machine virtuelle Java identifiera automatiquement et avec précision quelle méthode spécifique doit être appelée. Cependant, en raison de la transformation vers le haut, l'objet a perdra des méthodes différentes de la classe parent, telles que b1(). Certaines personnes pourraient se demander : n’est-ce pas inutile ? On peut certainement écrire comme ceci :
B a = new B();
a.a1();
En effet ! Mais cela perd les fonctionnalités de programmation orientées abstraction et réduit l’évolutivité. En fait, la transformation ascendante peut également réduire la charge de travail de programmation. Jetons un coup d'oeil à la classe d'affichage Monitor suivante :
package a.b; public class Monitor{ public void displayText() {} public void displayGraphics() {} } 液晶显示器类LCDMonitor是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"); } } 阴极射线管显示器类CRTMonitor自然也是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"); } } 等离子显示器PlasmaMonitor也是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"); } } 现在有一个MyMonitor类。假设没有向上转型,MyMonitor类代码如下: 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(); } } 可能你已经意识到上述代码有很多重复代码,而且也不易维护。有了向上转型,代码可以更为简洁: 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(); } } 我们也可以采用接口的方式,例如: package a.b; public interface Monitor { abstract void displayText(); abstract void displayGraphics(); } 将液晶显示器类LCDMonitor稍作修改: 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"); } }
2 Transformation vers le bas (transformation de la classe parent en sous-classe)
A类: package a.b; public class A { void aMthod() { System.out.println("A method"); } } A的子类B: package a.b; public class B extends A { void bMethod1() { System.out.println("B method 1"); } void bMethod2() { System.out.println("B method 2"); } } 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(); } } 从上面的代码我们可以得出这样一个结论:向下转型需要使用强制转换。运行C程序,控制台将输出: 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
En fait, B b2 = (B) vers le bas at a2 Les commentaires après le code de transformation indiquent déjà qu'une erreur d'exécution se produira. Pourquoi le code de transformation vers le bas dans la première phrase est-il correct, mais le code dans la deuxième phrase est faux ? En effet, a1 pointe vers un objet de la sous-classe B, donc bien sûr, l'objet instance b1 de la sous-classe B peut également pointer vers a1. Et a2 est un objet de classe parent, et l'objet de sous-classe b2 ne peut pas pointer vers l'objet de classe parent a2. Alors, comment puis-je éviter une ClassCastException d'exécution lors d'un downcast ? Utilisez simplement l'instanceof apprise dans la section 5.7.7. Modifions le code de la classe C :
A a2 = new A(); if (a2 instanceof B) { B b2 = (B) a2; b2.aMthod(); b2.bMethod1(); b2.bMethod2(); }
Après un traitement de cette manière, nous n'avons pas à nous soucier des exceptions ClassCastException lors de la conversion de type.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!