[JAVA] Polymorphisme

façon de penser de base

Utilisez le concept d'héritage ʻis-apour que le contour de l'instance soit reconnu par programme. Par exemple, une méthode pour reconnaître par programme une instancetrack générée à partir de la classe track comme une instance de la classe ʻautomobile.

Comment reconnaître par programme le contour d'une instance

Dans le cas des voitures et des camions ...

Car car =new Truck

①new Truck Créez une instance.

②Car car Que considérez-vous comme l'instance créée? Cette fois, l'instance a été créée à partir de la "classe de piste", mais cela signifie qu'elle est considérée comme une "voiture".

image

スクリーンショット 2018-03-04 11.14.42.png

スクリーンショット 2018-03-04 11.14.52.png

Attribuer l'instance générée à partir de la classe enfant à la classe parent

Façon de penser

Si vous affectez une instance créée à partir d'une classe enfant à une classe parent, les membres de la classe enfant ne peuvent pas être utilisés.

image

多様性(親インスタンスへの代入).png

Que se passe-t-il lorsque les classes parent et enfant ont des méthodes avec le même nom

Façon de penser

En raison du concept d'héritage, la méthode de la classe enfant est également appelée lorsque la méthode de la classe parent est appelée.

image

スクリーンショット 2018-03-02 11.45.17.png

-La figure ci-dessus a deux types: «Instance de l'assistant», qui est considérée comme «Assistant», et «Instance de l'assistant», qui est considérée comme «Caractère». -Chaque méthode run est appelée, mais si la méthode run est appelée dans l''instance Wizard qui est considérée comme Character, je me demande si la méthode de la classe Charactersera appelée ... -Comme la méthode de la ** classe enfant ** est appelée préférentiellement sur la base du concept d'héritage, l'instance de la classeWizard` est appelée.

Lorsque vous souhaitez modifier le plan de l'instance de la classe parent à la classe enfant

Façon de penser

En remplaçant par l'exemple ci-dessus, la méthode lorsque vous voulez changer l'instance wizard, qui est considérée comme Character, en l'instance wizard, qui est considérée comme Wizard.

Méthode de modification

** Penser normalement ... **

Wizard wizard2 = character;

Ça a l'air bien, mais j'obtiens une erreur avec ça ... La raison en est que l'instance «wizard» est considérée comme «Character», et l'instance «wizard» a été à peu près considérée comme «Character». Par conséquent, du point de vue de l'ordinateur, "Est-ce vraiment un" assistant "? Il y a d'autres" personnages ", non ??"

pour cette raison

Wizard wizard2 = (Wizard)character;

Vous devez utiliser l'opérateur de conversion pour forcer la classe à changer. Dans ce qui précède, il est modifié de force en une variable de type (Assistant).

Pourtant

Character character = new Hero;//Considérez le héros comme un personnage!
Wizard wizard2 = (Wizard)character;//Pensez au héros comme à une sorcière! (??)

Les erreurs ci-dessus peuvent survenir. -Créer une instance de héros qui est d'abord capturée en tant que personnage. -Créez une instance de héros qui peut être considérée comme une sorcière. Dans ce cas, ** La relation est-une ne tient pas **, vous obtiendrez donc l'erreur ClassCastException (le changement forcé par conversion est incorrect). ・ ○ Hero est un personnage. ・ × Hero est une sorcière.

En d'autres termes, les seules classes qui peuvent être modifiées de force par conversion sont les classes utilisées lors de la création de l'instance, ou les classes après ses classes enfants **.

Comment déterminer si le changement forcé par fonte est correct

Méthode

Pour déterminer si la conversion forcée par cast est correcte, java utilise l'opérateur ʻinstanceof. L'opérateur ʻinstanceof détermine s'il y a une incohérence lors de l'affectation au type spécifié par l'opérateur de conversion.

Exemple

if(character instanceof Wizard){//si,`character`À`Wizard`Si vous pouvez le considérer comme
 Wizard wizard2 = (Wizard)character;
}

Avantages de la diversité

Vous pouvez mettre en place le traitement

Façon de penser

En utilisant un tableau pour les variables de classe lors de la création d'une instance, il est possible d'effectuer un traitement par lots pour l'instance.

** Si vous n'utilisez pas de tableau ** Si vous voulez générer Hero1``Hero2``Hero3 à partir de la classe héros et Wizard1``Wizard2``Wizard3 à partir de la classe sorcière et laissez tout le monde attaquer

//Génération d'instance
Hero hero1 = new Hero();
Hero hero2 = new Hero();
Hero hero3 = new Hero();
Wizard wizard1 = new Wizard();
Wizard wizard2 = new Wizard();
Wizard wizard3 = new Wizard();

//Appel de méthode
hero1.attack();
hero2.attack();
hero3.attack();
wizard1.attack();
wizard1.attack();
wizard1.attack();

Dans ce cas, l'appel de méthode est répété de la même manière, et ce n'est pas cool ...

** Utilisation d'un tableau **

//Créer un tableau
Character[] character = new Character[6];

//Génération d'instance
Character character[0] = new Hero;
Character character[1] = new Hero;
Character character[2] = new Hero;
Character character[3] = new Wizard;
Character character[4] = new Wizard;
Character character[5] = new Wizard;

//Appel de méthode
for(Character ch : character){
 ch.attack();
}

Le traitement de la méthode est bien organisé et ça fait du bien!

Peut recevoir des arguments grossiers

Exemple

** Si vous voulez attaquer un monstre **

	public static void main(String[] args) {
		//Création de variables de tableau
		Monster[] monster = new Monster[4];
		//Générer une instance de monstre
		monster[0] = new Slime();
		monster[1] = new Slime();
		monster[2] = new Goblin();
		monster[3] = new Goblin();
		//Générer une instance de héros
		Hero hero = new Hero();
		//Attaquer les monstres
		hero.attack(monster[0]);
	}

public class Hero {
	void attack(Monster monster) {
		monster.hp-=10;
	}
}

En faisant cela, il n'est pas nécessaire de préparer l'argument de la «méthode d'attaque» de la classe «Hero» pour chaque type de monstre.

Il est possible de combiner le traitement de différents résultats de traitement

Façon de penser

Même si vous appelez une méthode avec le nom de classe de la classe parent, la méthode de la classe enfant est appelée, vous pouvez donc combiner les appels de méthode.

Exemple

Classe de slime

public class Slime extends Monster {
	public void run() {
		System.out.println("Le slime a gonflé et s'est enfui!");
	}
}

Classe de gobelin

public class Goblin extends Monster{
	public void run() {
		System.out.println("Le gobelin s'est enfui slapstick!");
	}
}

Classe de monstre


public abstract class Monster {
	String name;
	int hp = 50;
	public abstract void run();
}

Méthode principale

//Générer une instance de monstre
monster[0] = new Slime();
monster[1] = new Goblin();
//Méthode d'appel dans la classe monstre
for(Monster mo:monster) {
mo.run();

Résultat de sortie


Le slime a gonflé et s'est enfui!
Le gobelin s'est enfui slapstick!

Bien qu'il soit appelé par la classe monster, le contenu de la méthode de chaque classe est exécuté. À ce stade, il est nécessaire de définir une méthode à appeler à la méthode parente avec ʻabstrack`.

Recommended Posts

Polymorphisme
Polymorphisme
[Java] Polymorphisme
À propos du polymorphisme
Encapsulation, polymorphisme
java (mérites du polymorphisme)