Java learning_Behavior lorsqu'il y a un champ avec le même nom et une méthode avec le même nom dans deux classes dans une relation d'héritage

Préface

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.

Contenu de l'apprentissage

Vérification 1: instanciation = sous-classe, type de variable = superclasse

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.

Source de vérification

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 l'inspection

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.

Vérification 2: instanciation = sous-classe, type de variable = sous-classe

Cette fois, la classe à instancier et le type de variable sont alignés et vérifiés.

Source de vérification

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 l'inspection

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.

Extra: Comportement lorsque la méthode remplacée par la sous-classe est perdue

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é.

Source de vérification

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 l'inspection

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.

Impressions

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

Java learning_Behavior lorsqu'il y a un champ avec le même nom et une méthode avec le même nom dans deux classes dans une relation d'héritage
N'y a-t-il pas un conflit de nom lorsque enum a le même nom dans l'instruction switch?
gestion des erreurs wsimport (une classe / interface avec le même nom "xxx" est déjà utilisée)
[Head panic] Priorité lorsque des variables / méthodes portant le même nom sont utilisées dans des classes héritées
[Java] Comment rechercher des valeurs dans un tableau (ou une liste) avec la méthode contains
Comment afficher la valeur lorsqu'il y a un tableau dans le tableau
Lors de l'appel de sshpass depuis Java avec shell etc., il semble qu'il soit nécessaire d'avoir un chemin.
Une belle solution de contournement lorsque "avoir une instance de l'une des deux classes"
Déclarez une méthode qui a une valeur de retour Java avec le type de données de valeur de retour
Appelle la chaîne de caractères passée comme argument en tant que méthode avec send
Comment référencer une colonne lors du remplacement de la méthode de nom de colonne dans ActiveRecord
Lors de la réaffectation à un argument dans une méthode Ruby puis en appelant `super` → Celui réaffecté est utilisé
Quelle est la méthode principale en Java?
La cause n'est pas visible lors de l'appel de méthodes d'autres classes en java
Même en Java, je veux sortir vrai avec un == 1 && a == 2 && a == 3 (magie grise qui n'est pas tant que magie noire)
Créons une application TODO avec Java 12 Processing lorsqu'une requête arrive avec une HttpMethod inutilisée ・ Traitement lorsqu'une erreur se produit sur le serveur
Une histoire embarrassante qui a été traitée comme le même jour en essayant de comparer les dates du 31/03 et du 01/04 [Java / Calendar]
Traitement lorsqu'un ID qui n'existe pas dans la base de données est entré dans l'URL
Premiers pas avec JavaFX avec une application qui peut calculer la teneur en alcool lorsque le zéro fort est divisé par une bouchée