This is the sixth day of my participation in Gwen Challenge


Introduction: Three characteristics of object-oriented: encapsulation, inheritance, polymorphism, we have learned about encapsulation and inheritance, this chapter we will explain polymorphism in detail, this chapter knowledge needs to use inheritance knowledge, if you have not learned inheritance, please go out to the right, after learning and come back.

Why polymorphism is used:

Before we get to polymorphism, let’s look at a problem. There are two animals in need, a dog and a penguin. Now we need to write a program to feed the animal when the animal is hungry:

After analysis, we found that both animals had the same attributes (nickname: name, health value: Health, intimacy, love), and the same method (properties corresponding to the set/get methods and related printing methods), then optimize the system we both the same properties and methods can be further extracted form a common parent class animal, but we found that different animals to eat, eat different pet later restore physical strength value is different, If we look at the process of eating as a method, then the two kinds of eating methods are different.

Through analysis, we can get the following classes:

  • Animals: Attributes (common attributes), methods (common methods)

  • Dogs: Attributes (XX), methods (how dogs eat)

  • Penguins: Properties (XX), methods (how penguins eat)

  • Animal owners: Attributes (XX), methods (feeding method for dogs, feeding method for penguins)

  • Write test classes: animal owners feed their dogs, animal owners feed their penguins

The code is as follows:

The parent class:

package cn.hz;

/** * Pet, the parent of dogs and penguins. * *@author  hz
*/
public  class Pet {
	private String name = Anonymous;/ / nickname
	private int health = 100;/ / health value
	private int love = 0;/ / intimacy
	
	/** * has a parameter constructor. *@paramThe name nickname * /
	public Pet(a){}public Pet(String name) {
		this.name = name;
	}
	
	public void setName(String name) {
		this.name = name;
	}

	public void setHealth(int health) {
		this.health = health;
	}
	public void setLove(int love) {
		this.love = love;
	}

	public String getName(a) {
		return name;
	}
	public int getHealth(a) {
		return health;
	}
	public int getLove(a) {
		return love;
	}
	/** * Outputs pet information. * /
	public void print(a) {
		System.out.println("Confessions of a Pet: \n My Name is + this.name + 
				"The health value is."	+ this.health + "How close is the master?"
				+ this.love + "。"); }}Copy the code

The subclass:

package cn.hz;

/** * Dog, a subclass of pets. * *@author hz
 */
public class Dog extends Pet {
   private String strain;/ / varieties
   /** * has a parameter constructor. *@paramThe name nickname *@paramStrain * /
   public Dog(String name, String strain) {
      super(name); 
      this.strain = strain;
   }
   public String getStrain(a) {
      return strain;
   }
   /** * override the print method of the parent class. * /
   public void print(a){
      super.print(); // Call the print method of the parent class
      System.out.println("I am one." + this.strain + "。");
   }
   
   /** * Implements eating methods. * /
   public void eat(a) {
      if(getHealth()>=100){
         System.out.println("Dog"+this.getName() +"Full, no need to feed!");
      }else{
         this.setHealth(this.getHealth()+3);
         System.out.println("Dog"+this.getName() + "Full! Health increased by 3.); }}}Copy the code
package cn.hz;

/** * Penguin, a subclass of pets. * *@author  hz
 */
public class Penguin extends Pet {
	private String sex;/ / gender
	/** * has a parameter constructor. *@paramThe name nickname *@paramSex sex * /
	public Penguin(String name, String sex) {
		super(name);
		this.sex = sex;
	}
	public String getSex(a) {
		return sex;
	}
	/** * override the print method of the parent class. * /
	public void print(a) {
		super.print();
		System.out.println("The gender is" + this.sex + "。");
	}
	
	/** * Implements eating methods. * /
	public void eat(a) {
		if(getHealth()>=100){
			System.out.println("Penguin"+this.getName() +"Full, no need to feed!");
		}else{
			this.setHealth(this.getHealth()+5);
			System.out.println("Penguin"+this.getName() + "Full! Health increased by 3.); }}}Copy the code

Animal owners:

package cn.hz;

/** * Master class *@author  hz
 */
public class Master {
	private String name = "";// Master's name
	private int money = 0; / / silver piece number
	/** * has a parameter constructor. *@paramName Host name *@paramNumber of coins */
	public Master(String name, int money) {
		this.name = name;
		this.money = money;
	}
	
	public void setName(String name) {
		this.name = name;
	}

	public void setMoney(int money) {
		this.money = money;
	}

	public int getMoney(a) {
		return money;
	}
	public String getName(a) {
		return name;
	}
	/** * The owner feeds the Dog. * /
	public void feed(Dog dog) {
		dog.eat();
	}
	/** * The owner feeds the Penguin. * /
	public void feed(Penguin pgn) { pgn.eat(); }}Copy the code

The test class:

package cn.hz;
/** * Test class, adopt pets and feed them. *@author  hz
 */
public class Test {
	public static void main(String[] args) {
		Dog dog = new Dog("The European"."Shenarui");
		dog.setHealth(80); // Set the health value for normal feeding
		Penguin pgn = new Penguin(Nannan ""."Q sister");
		Master master=new Master("Mr. Wang".100);
		master.feed(dog);// The owner feeds the dog
		master.feed(pgn);// The owner feeds the penguins
		pgn.setHealth(80); // Set the health value for normal feeding
		master.feed(pgn);// The owner feeds the penguin again}}Copy the code

The demo effect is as follows:

Through the above code, we have realized the animal feeding function. If we adopt XXX pet again and need to feed XXX, what should we do?

  • Add XXX class, inherit Pet class, implement eating method
  • Modify Master class to add feeding method for XXX

At this time we will find the problem, for the above code, as long as there are new functions added, we need to modify the code frequently, the code scalability and maintainability is poor, how to optimize? One solution is provided in Java – polymorphism.

Ii. Polymorphism:

1. Definition:

Polymorphism is the ability to have many different manifestations or forms of the same behavior.

Polymorphism is the same interface, using different instances to perform different operations, as shown in the figure below:

For example, the animal owner needs to feed different animals, but the feeding object instances are different, so we can use multiple to achieve the feeding function.

2. Necessary conditions for the existence of polymorphism:

  • Inheritance: Write parent and subclass classes with inheritance relationships
  • Override: A subclass overrides a parent class method
  • Parent class references refer to subclass objects: Parent p = new Child(); – Automatic upward transition

When a method is called in polymorphic mode, the first check is made to see if the method exists in the parent class. If not, a compilation error occurs. If so, call the subclass’s method of the same name.

Benefits of polymorphism: it allows programs to be well extensible and can handle objects of all classes in general.

3. Polymorphic implementation:

There are two ways to implement polymorphism:

  • Implement polymorphism using a parent class as a method parameter
  • Implement polymorphism using the parent class as the method return value

For example, if we add a new animal, we need to modify the code. For example, if we add a new pet-cat class, what if we use polymorphism to optimize it?

First of all, we analyze two methods of animals all need to have to eat, but eat and implementation result is different, if we eat as a method, namely the method body is different, if we eat the methods defined in the parent class into abstract method, different subclasses to do different, so we directly feeding parent class at feeding time, As for the subclass, we don’t need the relationship, and when the subclass is instantiated, the parent class reference points to the subclass reference, which greatly improves the extensibility of our code.

The code is as follows:

Parent class: Defined as an abstract class, write abstract methods – eating methods

package cn.hz;

/** * Pet, the parent of dogs and penguins. *@author  hz
*/
public abstract class Pet {
	private String name = Anonymous;/ / nickname
	private int health = 100;/ / health value
	private int love = 0;/ / intimacy
	
	/** * abstract method eat(), responsible for pet eating function. * /
	public abstract void eat(a);
	
	/** * has a parameter constructor. *@paramThe name nickname * /
	public Pet(a){}public Pet(String name) {
		this.name = name;
	}
	
	public void setName(String name) {
		this.name = name;
	}

	public void setHealth(int health) {
		this.health = health;
	}

	public void setLove(int love) {
		this.love = love;
	}

	public String getName(a) {
		return name;
	}
	public int getHealth(a) {
		return health;
	}
	public int getLove(a) {
		return love;
	}
	/** * Outputs pet information. * /
	public void print(a) {
		System.out.println("Confessions of a Pet: \n My Name is + this.name + 
				"The health value is."	+ this.health + "How close is the master?"
				+ this.love + "。"); }}Copy the code

Subclass: A subclass overrides an abstract method of its parent class

package cn.hz;

/** * Penguin, a subclass of pets. *@author  hz
 */
public class Penguin extends Pet {
	private String sex;/ / gender
	/** * has a parameter constructor. *@paramThe name nickname *@paramSex sex * /
	public Penguin(String name, String sex) {
		super(name);
		this.sex = sex;
	}
	public String getSex(a) {
		return sex;
	}
	/** * override the print method of the parent class. * /
	public void print(a) {
		super.print();
		System.out.println("The gender is" + this.sex + "。");
	}
	
	/** * Implements eating methods. * /
	public void eat(a) {
		if(getHealth()>=100){
			System.out.println("Penguin"+this.getName() +"Full, no need to feed!");
		}else{
			this.setHealth(this.getHealth()+5);
			System.out.println("Penguin"+this.getName() + "Full! Health increased by 3.); }}}Copy the code
package cn.hz;

/** * Penguin, a subclass of pets. *@author  hz
 */
public class Penguin extends Pet {
	private String sex;/ / gender
	/** * has a parameter constructor. *@paramThe name nickname *@paramSex sex * /
	public Penguin(String name, String sex) {
		super(name);
		this.sex = sex;
	}
	public String getSex(a) {
		return sex;
	}
	/** * override the print method of the parent class. * /
	public void print(a) {
		super.print();
		System.out.println("The gender is" + this.sex + "。");
	}
	
	/** * Implements eating methods. * /
	public void eat(a) {
		if(getHealth()>=100){
			System.out.println("Penguin"+this.getName() +"Full, no need to feed!");
		}else{
			this.setHealth(this.getHealth()+5);
			System.out.println("Penguin"+this.getName() + "Full! Health increased by 3.); }}}Copy the code
package cn.hz;

/** * Dog, a subclass of pets. *@author  hz
 */
public class Dog extends Pet {
	private String strain;/ / varieties
	/** * has a parameter constructor. *@paramThe name nickname *@paramStrain * /
	public Dog(String name, String strain) {
		super(name); 
		this.strain = strain;
	}
	public String getStrain(a) {
		return strain;
	}
	/** * override the print method of the parent class. * /
	public void print(a){
		super.print(); // Call the print method of the parent class
		System.out.println("I am one." + this.strain + "。");
	}
	
	/** * Implements eating methods. * /
	public void eat(a) {
		if(getHealth()>=100){
			System.out.println("Dog"+this.getName() +"Full, no need to feed!");
		}else{
			this.setHealth(this.getHealth()+3);
			System.out.println("Dog"+this.getName() + "Full! Health increased by 3.); }}}Copy the code
package cn.hz;
/** * Cat, a subclass of pets. *@author  hz
 */
public class Cat extends Pet {
	private String color;/ / color
	public Cat(String name, String color) {
		super(name);
		this.color = color;
	}
	
	public void setColor(String color) {
		this.color = color;
	}

	public String getColor(a) {
		return color;
	}
	/** * implement eating method */
	public void eat(a) {
		if(getHealth()>=100){
			System.out.println("Dog"+this.getName() +"Full, no need to feed!");
		}else{
			this.setHealth(this.getHealth()+4);
			System.out.println("Cats"+this.getName() + "Full! Strength increased by 4."); }}}Copy the code

Pet owner class: feeding method is only one, parameter is parent class

package cn.hz; /** * Master class. * @author hz */ public class Master { private String name = ""; Private int money = 0; /** ** /** * */ public Master(String name, int money) {this.name = name; this.money = money; } public void setName(String name) { this.name = name; } public void setMoney(int money) { this.money = money; } public int getMoney() { return money; } public String getName() { return name; } /** * The owner feeds the pet. */ public void feed(Pet pet) { pet.eat(); }}Copy the code

Test classes: Parent class references point to subclass objects

package cn.hz;
/** * Test class, adopt pets and feed them. *@author  hz
 */
public class Test {
	public static void main(String[] args) {
		Dog dog = new Dog("The European"."Shenarui");
		Penguin pgn = new Penguin(Nannan ""."Q sister");
		Cat cat=new Cat("Tomcat"."Yellow");
		dog.setHealth(80); // Set the health value for normal feeding
		pgn.setHealth(80); // Set the health value for normal feeding
		cat.setHealth(80); // Set the health value for normal feeding
		Master master=new Master("Mr. Wang".100);
		master.feed(dog);// The owner feeds the dog
		master.feed(pgn);// The owner feeds the penguins
		master.feed(cat);// The owner feeds the cat}}Copy the code

By comparison, we can find that using the parent class as a method parameter, passing in the concrete child class, and using the parent class reference to point to the child class object can greatly reduce the code modification, thus improving the extensibility of the code.

Now let’s look at the parent class as the return value to implement polymorphism, if we have a new requirement, write code to implement the adoption of animals, if we do the traditional way, we need to define the adoption of different animals in the master class, what if we use polymorphism? So we only need to define the return value of the adopted animal method as animal class, and then return different subclasses through the specific determination of the method, the code is similar, omitted.

From the above example, we know that both the parent class as a method parameter and the parent class as a return value implement polymorphism, greatly improve the extensibility of the code, but pay attention to the type conversion problem when using polymorphism.

4. Advantages of polymorphism:

  • Decouple the types
  • replaceability
  • scalability
  • Interface,
  • flexibility
  • Simplify the sex