[JAVA] Polymorphism

basic way of thinking

Use the concept of inheritance ʻis-ato make the outline of the instance recognized programmatically. For example, a way to programmatically recognize atruck instance generated from the truckclass as an instance of thecar` class.

How to programmatically recognize the outline of an instance

In the case of automobiles and trucks ...

Car car =new Truck

①new Truck Create an instance.

②Car car What do you consider the created instance to be? This time, the instance was created from the "truck class", but it means that it is regarded as a "car".

image

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

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

Assign the instance generated from the child class to the parent class

Way of thinking

If you assign an instance created from a child class to a parent class, the members of the child class cannot be used.

image

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

What happens when the parent and child classes have methods with the same name

Way of thinking

Due to the concept of inheritance, the method of the child class is also called when the method of the parent class is called.

image

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

-There are two types of the above figure: Wizard instance, which is regarded as Wizard, and Wizard instance, which is regarded as Character. -Each method run is called, but if the method run is called in the Wizard instance which is regarded as Character, I wonder if the method of the Character class will be called ... -Since the method of ** child class ** is called preferentially based on the concept of inheritance, the instance of Wizard class is called.

When you want to change the outline of the instance from parent class to child class

Way of thinking

Replacing with the above example, the method when you want to change the wizard instance, which is regarded as Character, to the wizard instance, which is regarded as Wizard.

Modification method

** Thinking normally ... **

Wizard wizard2 = character;

It looks good, but I get an error with this ... The reason is that the wizard instance is regarded as Character, and the wizard instance has been generally regarded as Character. Therefore, from the computer's point of view, "Is this really awizard ?? There are other Characters, right ??"

for that reason

Wizard wizard2 = (Wizard)character;

You must use the cast operator to force the class to change. In the above, it is forcibly changed to a (Wizard) type variable.

However

Character character = new Hero;//Think of a hero as a character!
Wizard wizard2 = (Wizard)character;//Think of the hero as a witch! (??)

The above mistakes may occur. -Create a hero instance that is first captured as a character. -Create a hero instance that can be seen as a wizard. In this case, ** Is-a relationship does not hold **, so you will get the error ClassCastException (forced change by cast is wrong). ・ ○ A hero is a character. ・ × Hero is a witch.

In other words, the only classes that can be forcibly changed by casting are the class used when the instance was created or the class after its child class **.

How to determine if the forced change by cast is correct

Method

To determine if the forced conversion by cast is correct, java uses the ʻinstanceof operator. The ʻinstanceof operator determines if there is a contradiction when assigning to the type specified by the cast operator.

Example

if(character instanceof Wizard){//if,`character`To`Wizard`If you can consider it as
 Wizard wizard2 = (Wizard)character;
}

Benefits of diversity

You can put together the processing

Way of thinking

By using an array for class variables when creating an instance, it is possible to perform batch processing for the instance.

** If you don't use an array ** If you want to generate Hero1``Hero2``Hero3 from the hero class and Wizard1``Wizard2``Wizard3 from the wizard class and let everyone attack

//Instance generation
Hero hero1 = new Hero();
Hero hero2 = new Hero();
Hero hero3 = new Hero();
Wizard wizard1 = new Wizard();
Wizard wizard2 = new Wizard();
Wizard wizard3 = new Wizard();

//Method call
hero1.attack();
hero2.attack();
hero3.attack();
wizard1.attack();
wizard1.attack();
wizard1.attack();

In this case, the method call is repeated in the same way, and it's not good enough ...

** With arrays **

//Creating an array
Character[] character = new Character[6];

//Instance generation
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;

//Method call
for(Character ch : character){
 ch.attack();
}

The process of the method is neatly organized and feels good!

You can roughly receive arguments

Example

** If you want to attack a monster **

	public static void main(String[] args) {
		//Creating array variables
		Monster[] monster = new Monster[4];
		//Generating a monster instance
		monster[0] = new Slime();
		monster[1] = new Slime();
		monster[2] = new Goblin();
		monster[3] = new Goblin();
		//Generating a hero instance
		Hero hero = new Hero();
		//Attack monsters
		hero.attack(monster[0]);
	}

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

By doing this, it is not necessary to prepare the argument of the attack method of the Hero class for each type of monster.

Processing of different processing results can be combined

Way of thinking

Even if you call a method with the class name of the parent class, the method of the child class is called, so you can combine the method calls.

Example

Slime class

public class Slime extends Monster {
	public void run() {
		System.out.println("The slime swelled and ran away!");
	}
}

Goblin class

public class Goblin extends Monster{
	public void run() {
		System.out.println("The goblins ran away slapstick!");
	}
}

Monster class


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

Main method

//Generating a monster instance
monster[0] = new Slime();
monster[1] = new Goblin();
//Call method in monster class
for(Monster mo:monster) {
mo.run();

Output result


The slime swelled and ran away!
The goblins ran away slapstick!

Although it is called by the monster class, the method contents of each class are executed. At this time, it is necessary to define a method to be called to the parent method with ʻabstrack`.

Recommended Posts

Polymorphism
Polymorphism
[Java] Polymorphism
About polymorphism
Encapsulation, polymorphism
java (merits of polymorphism)