Cet article présente principalement l'explication détaillée et des exemples simples de transformation Java (transformation vers le haut ou vers le bas). Les amis dans le besoin peuvent se référer à
Dans la programmation Java, nous rencontrons souvent la conversion de type . >, la conversion de type d'objet comprend principalement la conversion vers le haut et la conversion vers le bas.
Transformation vers le haut
On dit souvent ceci dans la réalité : Cette personne sait chanter. Ici, peu importe que la personne soit noire ou blanche, adulte ou enfant, nous préférons donc utiliser le concept abstrait de « personne ». Pour un autre exemple, un moineau est un type d’oiseau (un sous-type d’oiseau) et un oiseau est un type d’animal (un sous-type d’animal). On le dit souvent dans la réalité : les moineaux sont des oiseaux. Ces deux déclarations sont en fait ce qu'on appelle la transformation ascendante. En termes simples, cela signifie la transformation d'une sous-classe en classe parent. Ceci est également conforme aux idées de programmation orientées abstraites prônées par Java. Regardons le code suivant :
package a.b;
public class A {
public void a1() {
System.out.println("Superclass");
}
}
Copier après la connexion
Une sous-classe B :
package a.b;
public class B extends A {
public void a1() {
System.out.println("Childrenclass"); //覆盖父类方法
}
public void b1(){} //B类定义了自己的新方法
}
Copier après la connexion
Classe C :
package a.b;
public class C {
public static void main(String[] args) {
A a = new B(); //向上转型
a.a1();
}
}
Copier après la connexion
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 ainsi :
B a = new B();
a.a1();
Copier après la connexion
C'est vrai ! 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. Examinons la classe de moniteur suivante Monitor :
package a.b;
public class Monitor{
public void displayText() {}
public void displayGraphics() {}
}
Copier après la connexion
Classe de moniteur LCD LCDMonitor est une sous-classe de 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");
}
}
Copier après la connexion
Cathode Ray La classe d'affichage à tube CRTMonitor est naturellement une sous-classe de 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");
}
}
Copier après la connexion
L'affichage plasma PlasmaMonitor est également une sous-classe de 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");
}
}
Copier après la connexion
Il existe désormais une classe MyMonitor. En supposant qu'il n'y ait pas de transformation vers le haut, le code de la classe MyMonitor est le suivant :
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();
}
}
Copier après la connexion
Vous avez peut-être réalisé que le code ci-dessus contient beaucoup de code en double et n'est pas facile à maintenir. Avec une transformation vers le haut, le code peut être plus concis :
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();
}
}
Copier après la connexion
On peut aussi utiliser l'
interface, par exemple :
package a.b;
public interface Monitor {
abstract void displayText();
abstract void displayGraphics();
}
Copier après la connexion
Modifiez légèrement la classe d'affichage à cristaux liquides 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");
}
}
Copier après la connexion
Les méthodes de modification des classes CRTMonitor et PlasmaMonitor sont similaires à LCDMonitor, mais MyMonitor n'a pas du tout besoin d'être modifié.
On voit que la transformation vers le haut reflète le polymorphisme
de la classe et améliore la simplicité du programme.
Transformation vers le bas
La transformation d'une sous-classe en classe parent est une transformation vers le haut, et inversement, la transformation d'une classe parent en sous-classe est une transformation vers le bas. Cependant, la transformation vers le bas peut poser certains problèmes : on peut dire qu'un moineau est un oiseau, mais on ne peut pas dire qu'un oiseau est un moineau. Regardons l'exemple suivant :
Classe A :
package a.b;
public class A {
void aMthod() {
System.out.println("A method");
}
}
Copier après la connexion
Sous-classe B de 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");
}
}
Copier après la connexion
Classe 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();
}
}
Copier après la connexion
À partir du code ci-dessus, nous pouvons tirer la conclusion que la transformation vers le bas nécessite l'utilisation de
cast . Exécutez le programme C et la console affichera :
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
Copier après la connexion
En fait, les commentaires après le code de transformation descendante en gras vous ont déjà averti qu'une erreur d'exécution se produirait. 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();
}
Copier après la connexion
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!