Je garderai un mémorandum de ce que j'ai appris pendant mes études pour la qualification Java Silver 11.
Il était difficile de comprendre le comportement quand il y avait un champ avec le même nom et une méthode avec le même nom dans deux classes qui ont une relation d'héritage, j'ai donc essayé d'apprendre tout en vérifiant.
Créez une instance d'une sous-classe, définissez-la dans une variable de type superclasse et vérifiez le comportement lors de son appel.
Classe astucieuse
class Astudy {
String val = "A";
void print() {
System.out.println("Un résultat d'étude->" + val);
}
}
Classe Bstudy
class Bstudy extends Astudy {
String val = "B";
void print() {
System.out.println("Sortie Bstudy->" + val);
}
}
Classe d'exécution
public class Study {
public static void main(String[] args) {
Astudy a = new Astudy();
Astudy b = new Bstudy();
System.out.println("Sortie de la variable a->" + a.val);
System.out.println("Sortie de la variable b->" + b.val);
a.print();
b.print();
}
}
Résultat de la vérification 1
Sortie de la variable a->A //Référencer une super classe
Sortie de la variable b->A //Référencer la super classe ...(1)
Un résultat d'étude->A //Appel d'une méthode de superclasse
Sortie Bstudy->B //Appel d'une méthode de sous-classe ...(2)
** Explication de (1) ** La classe Bstudy a été instanciée, mais la sortie est la valeur de la classe Astudy. En effet, l'objet qui a créé l'instance est défini sur le type de classe Astudy. Puisqu'il existe une règle selon laquelle ** les références de champ utilisent celle déclarée dans le type de variable **, la valeur définie dans la classe Astudy est sortie selon cette règle.
** Explication de (2) ** Contrairement aux champs, la méthode appelle ** les méthodes d'appel des classes instanciées **, donc la méthode print () de la classe Bstudy est exécutée. Bien qu'elle hérite de la classe Astudy, la destination de référence du champ est la valeur du champ défini dans la classe Bstudy car la portée n'est pas spécifiée pour la variable.
// Commentaire Portée = ceci ou super. Ceci ou, s'il est omis, renvoie à sa propre classe. Dans le cas de super, reportez-vous à la classe héritière.
Cette fois, la classe à instancier et le type de variable sont alignés et vérifiés.
Classe astucieuse
class Astudy {
String val = "A";
void print() {
System.out.println("Un résultat d'étude->" + val);
}
}
Classe Bstudy
class Bstudy extends Astudy {
String val = "B";
void print() {
System.out.println("Sortie Bstudy->" + val);
}
}
Classe d'exécution
public class Study {
public static void main(String[] args) {
Astudy a = new Astudy();
Bstudy b = new Bstudy(); //Changer le type en Bstudy
System.out.println("Sortie de la variable a->" + a.val);
System.out.println("Sortie de la variable b->" + b.val);
a.print();
b.print();
}
}
Résultat de la vérification 1
Sortie de la variable a->A //Référencer une super classe
Sortie de la variable b->B //Référence à une sous-classe ...(1)
Un résultat d'étude->A //Appel d'une méthode de superclasse
Sortie Bstudy->B //Appel d'une méthode de sous-classe ...(2)
** Explication de (1) ** En définissant l'instance sur une variable de type de sous-classe, la destination de référence de champ était différente de la vérification 1.
** Explication de (2) ** Même résultat que la vérification 1. Confirmez que cela n'affecte pas le type de la variable.
Dans la vérification 1 et la vérification 2, Bstudy a remplacé la méthode print () de la classe Astudy source d'héritage, mais le comportement lorsque cela n'était pas remplacé a été vérifié.
Classe astucieuse
class Astudy {
String val = "A";
void print() {
System.out.println("Un résultat d'étude->" + val);
}
}
Classe Bstudy
class Bstudy extends Astudy {
String val = "B";
// print()Supprimer la méthode
}
Classe d'exécution
public class Study {
public static void main(String[] args) {
Astudy a = new Astudy();
Astudy b = new Bstudy(); //Changer le type en Astudy
System.out.println("Sortie de la variable a->" + a.val);
System.out.println("Sortie de la variable b->" + b.val);
a.print();
b.print();
}
}
Résultat de la vérification 1
Sortie de la variable a->A //Référencer une super classe
Sortie de la variable b->A //Référencer la super classe ...(1)
Un résultat d'étude->A //Appel d'une méthode de superclasse
Un résultat d'étude->A //Appel d'une méthode de superclasse ...(2)
** Explication de (1) ** Le même résultat a été obtenu car le type de variable a été changé en superclasse comme lors de la vérification 1.
** Explication de (2) ** La méthode héritée a été appelée car il n'y a plus de méthodes dans la sous-classe. Le comportement lors de la création d'une instance d'une sous-classe est que la sous-classe et la superclasse sont combinées en une seule instance. À ce stade, si des méthodes avec la même définition correspondent à chaque classe, les méthodes de la sous-classe sont écrasées (remplacées). Puisque la vérification 1 est le modèle ci-dessus, la méthode de la classe Bstudy a été appelée. Comme la vérification de l'édition supplémentaire n'a pas été écrasée, la méthode de la classe Astudy a été appelée.
Il n'y avait aucun cas pratique où je devais être conscient de cela, donc j'étais confus au sujet de ma compréhension. La raison pour laquelle la méthode utilise la classe au moment de l'instance, alors que le champ est déclaré avec le type de variable, semble être due à la différence entre le moment de la compilation et le moment de l'exécution, mais cela est toujours bien compris. Ne pas. C'est un problème futur.
Recommended Posts